@atbash/sdk 0.12.0-dev.0 → 0.13.0-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
@@ -30,6 +30,15 @@ interface ValidatedEndpoint {
30
30
  declare function buildAllowedJudgeHosts(): ReadonlySet<string>;
31
31
  declare function validateJudgeEndpoint(judge?: JudgeEndpointConfig): ValidatedEndpoint;
32
32
 
33
+ interface ChainConfig {
34
+ readonly network: Network;
35
+ readonly blockchainRid: string;
36
+ readonly nodeUrls: readonly string[];
37
+ }
38
+ declare const PUBLIC_CHAIN: ChainConfig;
39
+ declare const PRIVATE_CHAIN: ChainConfig;
40
+ declare function chainForNetwork(network: Network): ChainConfig;
41
+
33
42
  /**
34
43
  * User-facing types. Two groups:
35
44
  * - Core types — the exact shapes the Rust core emits across the NAPI
@@ -290,7 +299,24 @@ interface AtbashLogger {
290
299
  interface AtbashOptions {
291
300
  endpoint?: string;
292
301
  timeoutMs?: number;
302
+ /**
303
+ * Full chain override — BRID + nodeUrls in one object. Wins over every
304
+ * other chain selector. Prefer this over paired `nodeUrls`/`blockchainRid`
305
+ * for anything but backwards compatibility.
306
+ */
307
+ chain?: ChainConfig;
308
+ /**
309
+ * Preset chain selector — `"public"` or `"private"`. Resolves to the
310
+ * matching `ChainConfig` via `chainForNetwork()`. Overridden by `chain`,
311
+ * overrides env `ATBASH_DEFAULT_CHAIN_NETWORK` and the config file.
312
+ */
313
+ network?: Network;
314
+ /**
315
+ * Explicit node URLs. Must be paired with `blockchainRid`. Passing one
316
+ * without the other throws — a BRID/nodes mismatch 404s every request.
317
+ */
293
318
  nodeUrls?: readonly string[];
319
+ /** Explicit BRID. Must be paired with `nodeUrls`. See {@link nodeUrls}. */
294
320
  blockchainRid?: string;
295
321
  /**
296
322
  * Default org name. When set, `judgeAction` / `auditToolCall` resolve
@@ -357,6 +383,10 @@ interface FromConfigOptions {
357
383
  keyPath?: string;
358
384
  /** Judge endpoint config — validated against the allowlist / self-hosted policy. */
359
385
  judge?: JudgeEndpointConfig;
386
+ /** See {@link AtbashOptions.chain}. */
387
+ chain?: ChainConfig;
388
+ /** See {@link AtbashOptions.network}. */
389
+ network?: Network;
360
390
  blockchainRid?: string;
361
391
  timeoutMs?: number;
362
392
  nodeUrls?: readonly string[];
@@ -408,12 +438,6 @@ interface LogToolCallOptions {
408
438
  orgEncryptionPubKey?: string;
409
439
  }
410
440
 
411
- interface ChainConfig {
412
- readonly network: Network;
413
- readonly blockchainRid: string;
414
- readonly nodeUrls: readonly string[];
415
- }
416
-
417
441
  declare class Atbash {
418
442
  readonly auth: AgentAuth;
419
443
  readonly endpoint: string;
@@ -437,6 +461,27 @@ declare class Atbash {
437
461
  * calls don't re-hit the dashboard. Cleared by `clearChainCache()`.
438
462
  */
439
463
  private readonly _chainCache;
464
+ /**
465
+ * The chain the constructor settled on. Used only where a lookup returns no
466
+ * answer — see {@link resolveChainFromMap}.
467
+ */
468
+ private readonly _defaultChain;
469
+ /**
470
+ * True when the caller named a chain outright — `chain`, `network`, or the
471
+ * paired `blockchainRid` + `nodeUrls`.
472
+ *
473
+ * Such a client is never re-pointed: not by the migration switch, and not by
474
+ * where an org turns out to live. Naming a chain is the caller saying "talk
475
+ * to this one", and silently routing elsewhere would make the argument a
476
+ * suggestion. A client that names nothing is the one that follows the org.
477
+ */
478
+ private readonly _explicitChain;
479
+ /**
480
+ * The fleet-wide chain switch, read once at construction. `resolve()` hits
481
+ * the config file on disk, so re-reading it per call would put a file read
482
+ * on every judge.
483
+ */
484
+ private readonly _forcedNetwork;
440
485
  /**
441
486
  * Short-TTL cache for `/api/ai/exists`. The `registered` field is
442
487
  * monotonic (once true, stays true), so most calls in a burst re-fetch
@@ -552,7 +597,9 @@ declare class Atbash {
552
597
  * 2. Per-chain subscription fallback — public + private records
553
598
  * are fetched in parallel, with `is_private_blockchain` and
554
599
  * `assigned_at` reconciling mixed states.
555
- * Defaults to the public chain when nothing else resolves.
600
+ * A lookup that names exactly one chain wins outright. Where it names
601
+ * neither (a brand-new org) or cannot choose between them, the client's
602
+ * configured default decides.
556
603
  */
557
604
  resolveChainForOrg(orgName: string): Promise<ChainConfig>;
558
605
  /**
@@ -606,6 +653,25 @@ declare class Atbash {
606
653
  * back to the client default (best-effort discovery).
607
654
  */
608
655
  private bridForOrg;
656
+ /**
657
+ * BRID for the client's configured default org, if it has one.
658
+ *
659
+ * Calls that carry no `orgName` argument are not chain-less: they still
660
+ * belong to `this.orgName`, and that org lives on exactly one chain. Routing
661
+ * them by the constructor's chain instead means a client configured
662
+ * `network: "private"` reads the private chain for an org that lives on
663
+ * public, and gets an empty answer rather than an error. So where an org is
664
+ * known the org decides the chain, and the constructor's chain is what is
665
+ * left when no org is known at all — the order `resolveAgentLookupNetwork`
666
+ * already applies to agent metadata reads, and the order the dashboard
667
+ * applies in `resolveChainForWallet`.
668
+ *
669
+ * Undefined when there is no default org, so callers keep falling back to
670
+ * the client default.
671
+ */
672
+ /** The switch's chain, unless this client named one of its own. */
673
+ private forcedNetwork;
674
+ private defaultOrgBrid;
609
675
  private raiseIfError;
610
676
  /** Wrap a failed HTTP *response* (non-2xx / non-200) as an AtbashAPIError. */
611
677
  private httpError;
@@ -695,7 +761,14 @@ interface AtbashUserConfig {
695
761
  * only way a non-allowlisted judge host is accepted.
696
762
  */
697
763
  judgeVerifyPubKey?: string;
698
- blockchainRid?: string;
764
+ /**
765
+ * `"private"` pins every org to the private chain regardless of where the
766
+ * dashboard says it lives — the migration switch. Leave it unset for the
767
+ * normal mode, where each org's own chain decides. There is no `"public"`
768
+ * value; a caller that wants one specific chain passes `chain` or `network`
769
+ * at construction instead.
770
+ */
771
+ defaultChainNetwork?: Network;
699
772
  provider?: string;
700
773
  providerModel?: string;
701
774
  /** "1" / "true" turns on verbose diagnostics. See AtbashOptions.debug. */
@@ -1398,4 +1471,4 @@ declare function containsSecret(text: string): boolean;
1398
1471
  declare function createMemorySnapshot(entries: MemoryEntry[], takenAt: number): MemorySnapshot;
1399
1472
  declare function diffMemorySnapshots(before: MemorySnapshot, after: MemorySnapshot): MemoryDiffResult;
1400
1473
 
1401
- export { type ActionType, type AgentAuth, type AgentLookupOptions, 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, HttpClient, HttpTransportError, 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, getActiveAgentMemory, getActiveMemoryId, getConfigDir, getConfigPath, getMemoryById, getMemoryHistory, getRecentAgentMemory, 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 };
1474
+ export { type ActionType, type AgentAuth, type AgentLookupOptions, type AgentMemoryEntry, type AgentPolicy, type AnomalySeverity, type AnomalyType, Atbash, AtbashAPIError, type AtbashLogger, type AtbashOptions, type AtbashUserConfig, BOOT_SYNC_HINT, type ChainConfig, 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, HttpClient, HttpTransportError, 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, PRIVATE_CHAIN, PUBLIC_CHAIN, 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, chainForNetwork, chooseKeyPath, claimHashHex, classifyMemoryRead, classifyMemoryWrite, columnAad, commitMemoryVersion, containsEvasionCharacters, containsSecret, createFileLogger, createMemoryGuardManager, createMemorySnapshot, decryptForOrg, decryptMemoryContent, defaultPluginLogPath, defaultPointerPath, deriveMemoryKey, derivePublicKey, diffMemorySnapshots, encryptForOrg, encryptMemoryContent, encryptedLength, flushTelemetry, generateKeypair, getActiveAgentMemory, getActiveMemoryId, getConfigDir, getConfigPath, getMemoryById, getMemoryHistory, getRecentAgentMemory, 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
@@ -30,6 +30,15 @@ interface ValidatedEndpoint {
30
30
  declare function buildAllowedJudgeHosts(): ReadonlySet<string>;
31
31
  declare function validateJudgeEndpoint(judge?: JudgeEndpointConfig): ValidatedEndpoint;
32
32
 
33
+ interface ChainConfig {
34
+ readonly network: Network;
35
+ readonly blockchainRid: string;
36
+ readonly nodeUrls: readonly string[];
37
+ }
38
+ declare const PUBLIC_CHAIN: ChainConfig;
39
+ declare const PRIVATE_CHAIN: ChainConfig;
40
+ declare function chainForNetwork(network: Network): ChainConfig;
41
+
33
42
  /**
34
43
  * User-facing types. Two groups:
35
44
  * - Core types — the exact shapes the Rust core emits across the NAPI
@@ -290,7 +299,24 @@ interface AtbashLogger {
290
299
  interface AtbashOptions {
291
300
  endpoint?: string;
292
301
  timeoutMs?: number;
302
+ /**
303
+ * Full chain override — BRID + nodeUrls in one object. Wins over every
304
+ * other chain selector. Prefer this over paired `nodeUrls`/`blockchainRid`
305
+ * for anything but backwards compatibility.
306
+ */
307
+ chain?: ChainConfig;
308
+ /**
309
+ * Preset chain selector — `"public"` or `"private"`. Resolves to the
310
+ * matching `ChainConfig` via `chainForNetwork()`. Overridden by `chain`,
311
+ * overrides env `ATBASH_DEFAULT_CHAIN_NETWORK` and the config file.
312
+ */
313
+ network?: Network;
314
+ /**
315
+ * Explicit node URLs. Must be paired with `blockchainRid`. Passing one
316
+ * without the other throws — a BRID/nodes mismatch 404s every request.
317
+ */
293
318
  nodeUrls?: readonly string[];
319
+ /** Explicit BRID. Must be paired with `nodeUrls`. See {@link nodeUrls}. */
294
320
  blockchainRid?: string;
295
321
  /**
296
322
  * Default org name. When set, `judgeAction` / `auditToolCall` resolve
@@ -357,6 +383,10 @@ interface FromConfigOptions {
357
383
  keyPath?: string;
358
384
  /** Judge endpoint config — validated against the allowlist / self-hosted policy. */
359
385
  judge?: JudgeEndpointConfig;
386
+ /** See {@link AtbashOptions.chain}. */
387
+ chain?: ChainConfig;
388
+ /** See {@link AtbashOptions.network}. */
389
+ network?: Network;
360
390
  blockchainRid?: string;
361
391
  timeoutMs?: number;
362
392
  nodeUrls?: readonly string[];
@@ -408,12 +438,6 @@ interface LogToolCallOptions {
408
438
  orgEncryptionPubKey?: string;
409
439
  }
410
440
 
411
- interface ChainConfig {
412
- readonly network: Network;
413
- readonly blockchainRid: string;
414
- readonly nodeUrls: readonly string[];
415
- }
416
-
417
441
  declare class Atbash {
418
442
  readonly auth: AgentAuth;
419
443
  readonly endpoint: string;
@@ -437,6 +461,27 @@ declare class Atbash {
437
461
  * calls don't re-hit the dashboard. Cleared by `clearChainCache()`.
438
462
  */
439
463
  private readonly _chainCache;
464
+ /**
465
+ * The chain the constructor settled on. Used only where a lookup returns no
466
+ * answer — see {@link resolveChainFromMap}.
467
+ */
468
+ private readonly _defaultChain;
469
+ /**
470
+ * True when the caller named a chain outright — `chain`, `network`, or the
471
+ * paired `blockchainRid` + `nodeUrls`.
472
+ *
473
+ * Such a client is never re-pointed: not by the migration switch, and not by
474
+ * where an org turns out to live. Naming a chain is the caller saying "talk
475
+ * to this one", and silently routing elsewhere would make the argument a
476
+ * suggestion. A client that names nothing is the one that follows the org.
477
+ */
478
+ private readonly _explicitChain;
479
+ /**
480
+ * The fleet-wide chain switch, read once at construction. `resolve()` hits
481
+ * the config file on disk, so re-reading it per call would put a file read
482
+ * on every judge.
483
+ */
484
+ private readonly _forcedNetwork;
440
485
  /**
441
486
  * Short-TTL cache for `/api/ai/exists`. The `registered` field is
442
487
  * monotonic (once true, stays true), so most calls in a burst re-fetch
@@ -552,7 +597,9 @@ declare class Atbash {
552
597
  * 2. Per-chain subscription fallback — public + private records
553
598
  * are fetched in parallel, with `is_private_blockchain` and
554
599
  * `assigned_at` reconciling mixed states.
555
- * Defaults to the public chain when nothing else resolves.
600
+ * A lookup that names exactly one chain wins outright. Where it names
601
+ * neither (a brand-new org) or cannot choose between them, the client's
602
+ * configured default decides.
556
603
  */
557
604
  resolveChainForOrg(orgName: string): Promise<ChainConfig>;
558
605
  /**
@@ -606,6 +653,25 @@ declare class Atbash {
606
653
  * back to the client default (best-effort discovery).
607
654
  */
608
655
  private bridForOrg;
656
+ /**
657
+ * BRID for the client's configured default org, if it has one.
658
+ *
659
+ * Calls that carry no `orgName` argument are not chain-less: they still
660
+ * belong to `this.orgName`, and that org lives on exactly one chain. Routing
661
+ * them by the constructor's chain instead means a client configured
662
+ * `network: "private"` reads the private chain for an org that lives on
663
+ * public, and gets an empty answer rather than an error. So where an org is
664
+ * known the org decides the chain, and the constructor's chain is what is
665
+ * left when no org is known at all — the order `resolveAgentLookupNetwork`
666
+ * already applies to agent metadata reads, and the order the dashboard
667
+ * applies in `resolveChainForWallet`.
668
+ *
669
+ * Undefined when there is no default org, so callers keep falling back to
670
+ * the client default.
671
+ */
672
+ /** The switch's chain, unless this client named one of its own. */
673
+ private forcedNetwork;
674
+ private defaultOrgBrid;
609
675
  private raiseIfError;
610
676
  /** Wrap a failed HTTP *response* (non-2xx / non-200) as an AtbashAPIError. */
611
677
  private httpError;
@@ -695,7 +761,14 @@ interface AtbashUserConfig {
695
761
  * only way a non-allowlisted judge host is accepted.
696
762
  */
697
763
  judgeVerifyPubKey?: string;
698
- blockchainRid?: string;
764
+ /**
765
+ * `"private"` pins every org to the private chain regardless of where the
766
+ * dashboard says it lives — the migration switch. Leave it unset for the
767
+ * normal mode, where each org's own chain decides. There is no `"public"`
768
+ * value; a caller that wants one specific chain passes `chain` or `network`
769
+ * at construction instead.
770
+ */
771
+ defaultChainNetwork?: Network;
699
772
  provider?: string;
700
773
  providerModel?: string;
701
774
  /** "1" / "true" turns on verbose diagnostics. See AtbashOptions.debug. */
@@ -1398,4 +1471,4 @@ declare function containsSecret(text: string): boolean;
1398
1471
  declare function createMemorySnapshot(entries: MemoryEntry[], takenAt: number): MemorySnapshot;
1399
1472
  declare function diffMemorySnapshots(before: MemorySnapshot, after: MemorySnapshot): MemoryDiffResult;
1400
1473
 
1401
- export { type ActionType, type AgentAuth, type AgentLookupOptions, 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, HttpClient, HttpTransportError, 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, getActiveAgentMemory, getActiveMemoryId, getConfigDir, getConfigPath, getMemoryById, getMemoryHistory, getRecentAgentMemory, 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 };
1474
+ export { type ActionType, type AgentAuth, type AgentLookupOptions, type AgentMemoryEntry, type AgentPolicy, type AnomalySeverity, type AnomalyType, Atbash, AtbashAPIError, type AtbashLogger, type AtbashOptions, type AtbashUserConfig, BOOT_SYNC_HINT, type ChainConfig, 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, HttpClient, HttpTransportError, 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, PRIVATE_CHAIN, PUBLIC_CHAIN, 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, chainForNetwork, chooseKeyPath, claimHashHex, classifyMemoryRead, classifyMemoryWrite, columnAad, commitMemoryVersion, containsEvasionCharacters, containsSecret, createFileLogger, createMemoryGuardManager, createMemorySnapshot, decryptForOrg, decryptMemoryContent, defaultPluginLogPath, defaultPointerPath, deriveMemoryKey, derivePublicKey, diffMemorySnapshots, encryptForOrg, encryptMemoryContent, encryptedLength, flushTelemetry, generateKeypair, getActiveAgentMemory, getActiveMemoryId, getConfigDir, getConfigPath, getMemoryById, getMemoryHistory, getRecentAgentMemory, 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
@@ -2869,10 +2869,13 @@ __export(src_ts_exports, {
2869
2869
  KEY_FILENAMES: () => KEY_FILENAMES,
2870
2870
  MemoryGuardManager: () => MemoryGuardManager,
2871
2871
  MemoryIntegrityError: () => MemoryIntegrityError,
2872
+ PRIVATE_CHAIN: () => PRIVATE_CHAIN,
2873
+ PUBLIC_CHAIN: () => PUBLIC_CHAIN,
2872
2874
  PointerStore: () => PointerStore,
2873
2875
  SignatureVerificationError: () => SignatureVerificationError,
2874
2876
  bootSyncFailureLine: () => bootSyncFailureLine,
2875
2877
  buildAllowedJudgeHosts: () => buildAllowedJudgeHosts,
2878
+ chainForNetwork: () => chainForNetwork,
2876
2879
  chooseKeyPath: () => chooseKeyPath,
2877
2880
  claimHashHex: () => claimHashHex,
2878
2881
  classifyMemoryRead: () => classifyMemoryRead,
@@ -3394,11 +3397,34 @@ var ENV_MAP = {
3394
3397
  judgeEndpoint: "ATBASH_ENDPOINT",
3395
3398
  // Same variable name the Hermes plugin already documents.
3396
3399
  judgeVerifyPubKey: "ATBASH_JUDGE_VERIFY_PUBKEY",
3397
- blockchainRid: "ATBASH_BLOCKCHAIN_RID",
3400
+ defaultChainNetwork: "ATBASH_DEFAULT_CHAIN_NETWORK",
3398
3401
  provider: "ATBASH_PROVIDER",
3399
3402
  providerModel: "ATBASH_PROVIDER_MODEL",
3400
3403
  debug: "ATBASH_DEBUG"
3401
3404
  };
3405
+ var DEPRECATED_ENV_VARS = ["ATBASH_BLOCKCHAIN_RID"];
3406
+ var DEPRECATED_CONFIG_FIELDS = ["blockchainRid"];
3407
+ var deprecatedWarned = false;
3408
+ function warnDeprecatedEnvVarsOnce(log = console.warn) {
3409
+ if (deprecatedWarned) return;
3410
+ for (const name2 of DEPRECATED_ENV_VARS) {
3411
+ if (process.env[name2]) {
3412
+ deprecatedWarned = true;
3413
+ log(
3414
+ `[atbash] ${name2} is ignored \u2014 each org's chain is resolved from the dashboard; set ATBASH_DEFAULT_CHAIN_NETWORK=private only to pin everything to private`
3415
+ );
3416
+ }
3417
+ }
3418
+ const fileConfig = loadUserConfig();
3419
+ for (const field of DEPRECATED_CONFIG_FIELDS) {
3420
+ if (fileConfig[field]) {
3421
+ deprecatedWarned = true;
3422
+ log(
3423
+ `[atbash] "${field}" in ${getConfigPath()} is ignored \u2014 pass \`chain\` or \`network\` at construction instead`
3424
+ );
3425
+ }
3426
+ }
3427
+ }
3402
3428
  function getConfigDir() {
3403
3429
  const home2 = process.env.HOME || (0, import_node_os3.homedir)() || "";
3404
3430
  return (0, import_node_path3.join)(home2, ".config", "atbash");
@@ -3440,11 +3466,41 @@ function resolve(key3, flagValue) {
3440
3466
  if (fileVal != null) return String(fileVal);
3441
3467
  return "";
3442
3468
  }
3469
+ function forcedChainNetwork(flagValue) {
3470
+ const raw2 = resolve("defaultChainNetwork", flagValue);
3471
+ if (!raw2) return void 0;
3472
+ if (raw2 !== "public" && raw2 !== "private") {
3473
+ throw new Error(
3474
+ `ATBASH_DEFAULT_CHAIN_NETWORK / defaultChainNetwork must be "public" or "private", got ${JSON.stringify(raw2)} \u2014 unset it to let each org's chain decide.`
3475
+ );
3476
+ }
3477
+ return raw2;
3478
+ }
3443
3479
 
3444
3480
  // src-ts/client.ts
3445
3481
  function generateToolCallId() {
3446
3482
  return `tc-${Date.now()}-${randomHex(4)}`;
3447
3483
  }
3484
+ function resolveConstructorChain(options) {
3485
+ if (options.chain) return options.chain;
3486
+ const hasNodeUrls = options.nodeUrls !== void 0;
3487
+ const hasBrid = options.blockchainRid !== void 0;
3488
+ if (hasNodeUrls !== hasBrid) {
3489
+ throw new Error(
3490
+ 'nodeUrls and blockchainRid must be provided together \u2014 passing one without the other 404s every chain request. Prefer `chain: PUBLIC_CHAIN | PRIVATE_CHAIN` or `network: "public" | "private"`.'
3491
+ );
3492
+ }
3493
+ if (hasNodeUrls && hasBrid) {
3494
+ const brid = options.blockchainRid;
3495
+ const derivedNetwork = options.network ?? (brid === PUBLIC_CHAIN.blockchainRid ? "public" : brid === PRIVATE_CHAIN.blockchainRid ? "private" : "private");
3496
+ return {
3497
+ network: derivedNetwork,
3498
+ blockchainRid: brid,
3499
+ nodeUrls: options.nodeUrls
3500
+ };
3501
+ }
3502
+ return chainForNetwork(options.network ?? forcedChainNetwork() ?? "private");
3503
+ }
3448
3504
  var Atbash = class _Atbash {
3449
3505
  auth;
3450
3506
  endpoint;
@@ -3468,6 +3524,27 @@ var Atbash = class _Atbash {
3468
3524
  * calls don't re-hit the dashboard. Cleared by `clearChainCache()`.
3469
3525
  */
3470
3526
  _chainCache = /* @__PURE__ */ new Map();
3527
+ /**
3528
+ * The chain the constructor settled on. Used only where a lookup returns no
3529
+ * answer — see {@link resolveChainFromMap}.
3530
+ */
3531
+ _defaultChain;
3532
+ /**
3533
+ * True when the caller named a chain outright — `chain`, `network`, or the
3534
+ * paired `blockchainRid` + `nodeUrls`.
3535
+ *
3536
+ * Such a client is never re-pointed: not by the migration switch, and not by
3537
+ * where an org turns out to live. Naming a chain is the caller saying "talk
3538
+ * to this one", and silently routing elsewhere would make the argument a
3539
+ * suggestion. A client that names nothing is the one that follows the org.
3540
+ */
3541
+ _explicitChain;
3542
+ /**
3543
+ * The fleet-wide chain switch, read once at construction. `resolve()` hits
3544
+ * the config file on disk, so re-reading it per call would put a file read
3545
+ * on every judge.
3546
+ */
3547
+ _forcedNetwork;
3471
3548
  /**
3472
3549
  * Short-TTL cache for `/api/ai/exists`. The `registered` field is
3473
3550
  * monotonic (once true, stays true), so most calls in a burst re-fetch
@@ -3500,8 +3577,13 @@ var Atbash = class _Atbash {
3500
3577
  } : { endpoint: options.endpoint }
3501
3578
  );
3502
3579
  this.endpoint = validated.url;
3503
- this.nodeUrls = options.nodeUrls ? [...options.nodeUrls] : DEFAULT_CHROMIA_NODE_URLS;
3504
- this.blockchainRid = options.blockchainRid ?? native.DEFAULT_BLOCKCHAIN_RID;
3580
+ const resolvedChain = resolveConstructorChain(options);
3581
+ this.nodeUrls = [...resolvedChain.nodeUrls];
3582
+ this.blockchainRid = resolvedChain.blockchainRid;
3583
+ this._defaultChain = resolvedChain;
3584
+ this._explicitChain = options.chain !== void 0 || options.network !== void 0 || options.blockchainRid !== void 0 && options.nodeUrls !== void 0;
3585
+ this._forcedNetwork = forcedChainNetwork();
3586
+ warnDeprecatedEnvVarsOnce((msg) => options.logger?.warn?.(msg));
3505
3587
  this.orgName = options.orgName;
3506
3588
  this.verifyPubKey = validated.verifyPubKey ?? void 0;
3507
3589
  this.orgEncryptionPubKey = options.orgEncryptionPubKey;
@@ -3577,10 +3659,11 @@ var Atbash = class _Atbash {
3577
3659
  );
3578
3660
  const agentKey = resolve("agentKey", options.agentKey);
3579
3661
  const auth = agentKey ? native.loadAgent(agentKey) : loadAgentFromFile(options.keyPath);
3580
- const blockchainRid = resolve("blockchainRid", options.blockchainRid) || void 0;
3581
3662
  return new _Atbash(auth.privkey, {
3582
3663
  endpoint: validated.url,
3583
- blockchainRid,
3664
+ chain: options.chain,
3665
+ network: options.network,
3666
+ blockchainRid: options.blockchainRid,
3584
3667
  timeoutMs: options.timeoutMs,
3585
3668
  nodeUrls: options.nodeUrls,
3586
3669
  orgName: options.orgName,
@@ -3621,7 +3704,7 @@ var Atbash = class _Atbash {
3621
3704
  return this.track("checkAgentExists", pk, async () => {
3622
3705
  const query = { pubkey: pk };
3623
3706
  if (network) query.network = network;
3624
- const brid = this.bridFromChainOpts(network ? { network } : void 0);
3707
+ const brid = network ? this.bridFromChainOpts({ network }) : await this.defaultOrgBrid();
3625
3708
  const resp = await this.http.get(
3626
3709
  "/api/ai/exists",
3627
3710
  query,
@@ -3672,7 +3755,7 @@ var Atbash = class _Atbash {
3672
3755
  };
3673
3756
  }
3674
3757
  const toolCallId = generateToolCallId();
3675
- const brid = this.bridFromChainOpts(options.chainOpts);
3758
+ const brid = options.chainOpts?.blockchainRid || options.chainOpts?.network ? this.bridFromChainOpts(options.chainOpts) : await this.defaultOrgBrid() ?? this.blockchainRid;
3676
3759
  const orgKey = options.orgEncryptionPubKey ?? this.orgEncryptionPubKey ?? this._orgKeyFromChain;
3677
3760
  try {
3678
3761
  const signedHex = orgKey ? signEncryptedToolCall(
@@ -3723,7 +3806,11 @@ var Atbash = class _Atbash {
3723
3806
  throw new Error("action is required and cannot be empty.");
3724
3807
  }
3725
3808
  let chainOpts = options.chainOpts;
3726
- if (options.orgName) {
3809
+ if (options.orgName && this._explicitChain) {
3810
+ chainOpts = options.chainOpts ?? { network: this._defaultChain.network };
3811
+ } else if (options.orgName && this.forcedNetwork()) {
3812
+ chainOpts = { network: this.forcedNetwork() };
3813
+ } else if (options.orgName) {
3727
3814
  const cached = this._chainCache.get(options.orgName);
3728
3815
  if (cached) {
3729
3816
  chainOpts = { network: cached.network };
@@ -3957,7 +4044,7 @@ var Atbash = class _Atbash {
3957
4044
  const resp = await this.http.get(
3958
4045
  "/api/v1/judge",
3959
4046
  { tool_call_id: judgmentId, agent_pubkey: pk },
3960
- this.authHeaders()
4047
+ this.authHeaders(await this.defaultOrgBrid())
3961
4048
  );
3962
4049
  await this.raiseIfError(resp);
3963
4050
  const data = await this.json(resp) ?? {};
@@ -3977,7 +4064,11 @@ var Atbash = class _Atbash {
3977
4064
  return this.track(
3978
4065
  "getToolCalls",
3979
4066
  void 0,
3980
- () => this.riskEngineRecords("tool-calls", { limit: maxCount })
4067
+ async () => this.riskEngineRecords(
4068
+ "tool-calls",
4069
+ { limit: maxCount },
4070
+ await this.defaultOrgBrid()
4071
+ )
3981
4072
  );
3982
4073
  }
3983
4074
  async getOrgToolCalls(orgName, maxCount) {
@@ -3994,24 +4085,31 @@ var Atbash = class _Atbash {
3994
4085
  return this.track(
3995
4086
  "getAgentToolCalls",
3996
4087
  agentPubkey,
3997
- () => this.riskEngineRecords("agent-tool-calls", {
3998
- agent: agentPubkey,
3999
- limit: maxCount
4000
- })
4088
+ async () => this.riskEngineRecords(
4089
+ "agent-tool-calls",
4090
+ { agent: agentPubkey, limit: maxCount },
4091
+ await this.defaultOrgBrid()
4092
+ )
4001
4093
  );
4002
4094
  }
4003
4095
  async getToolCallCount() {
4004
4096
  return this.track("getToolCallCount", void 0, async () => {
4005
- const raw2 = await this.riskEngineGet("tool-call-count", {});
4097
+ const raw2 = await this.riskEngineGet(
4098
+ "tool-call-count",
4099
+ {},
4100
+ await this.defaultOrgBrid()
4101
+ );
4006
4102
  const n = Number(raw2);
4007
4103
  return Number.isFinite(n) ? n : 0;
4008
4104
  });
4009
4105
  }
4010
4106
  async getToolCallFull(toolCallId) {
4011
4107
  return this.track("getToolCallFull", void 0, async () => {
4012
- const raw2 = await this.riskEngineGet("tool-call-full", {
4013
- tool_call_id: toolCallId
4014
- });
4108
+ const raw2 = await this.riskEngineGet(
4109
+ "tool-call-full",
4110
+ { tool_call_id: toolCallId },
4111
+ await this.defaultOrgBrid()
4112
+ );
4015
4113
  if (!isRecord(raw2)) return null;
4016
4114
  return toToolCallFull(raw2);
4017
4115
  });
@@ -4097,7 +4195,7 @@ var Atbash = class _Atbash {
4097
4195
  const resp = await this.http.get(
4098
4196
  "/api/insurance",
4099
4197
  { action: "safety-stats" },
4100
- this.authHeaders()
4198
+ this.authHeaders(await this.defaultOrgBrid())
4101
4199
  );
4102
4200
  await this.raiseIfError(resp);
4103
4201
  const data = await this.json(resp) ?? {};
@@ -4153,10 +4251,15 @@ var Atbash = class _Atbash {
4153
4251
  * 2. Per-chain subscription fallback — public + private records
4154
4252
  * are fetched in parallel, with `is_private_blockchain` and
4155
4253
  * `assigned_at` reconciling mixed states.
4156
- * Defaults to the public chain when nothing else resolves.
4254
+ * A lookup that names exactly one chain wins outright. Where it names
4255
+ * neither (a brand-new org) or cannot choose between them, the client's
4256
+ * configured default decides.
4157
4257
  */
4158
4258
  async resolveChainForOrg(orgName) {
4159
4259
  const name2 = orgName.trim();
4260
+ if (this._explicitChain) return this._defaultChain;
4261
+ const forced = this.forcedNetwork();
4262
+ if (forced) return chainForNetwork(forced);
4160
4263
  const cached = this._chainCache.get(name2);
4161
4264
  if (cached) return cached;
4162
4265
  const mapNetwork = await this.getActiveNetworkForOrg(name2);
@@ -4188,7 +4291,7 @@ var Atbash = class _Atbash {
4188
4291
  return PRIVATE_CHAIN;
4189
4292
  }
4190
4293
  if (pubSub && privSub) {
4191
- const chain = privSub.assigned_at > pubSub.assigned_at ? PRIVATE_CHAIN : PUBLIC_CHAIN;
4294
+ const chain = privSub.assigned_at === pubSub.assigned_at ? this._defaultChain : privSub.assigned_at > pubSub.assigned_at ? PRIVATE_CHAIN : PUBLIC_CHAIN;
4192
4295
  this._chainCache.set(orgName, chain);
4193
4296
  return chain;
4194
4297
  }
@@ -4209,8 +4312,8 @@ var Atbash = class _Atbash {
4209
4312
  this.endpoint
4210
4313
  );
4211
4314
  }
4212
- this._chainCache.set(orgName, PUBLIC_CHAIN);
4213
- return PUBLIC_CHAIN;
4315
+ this._chainCache.set(orgName, this._defaultChain);
4316
+ return this._defaultChain;
4214
4317
  }
4215
4318
  /** Drop any cached chain resolutions. Useful in tests. */
4216
4319
  clearChainCache() {
@@ -4261,6 +4364,7 @@ var Atbash = class _Atbash {
4261
4364
  async resolveAgentLookupNetwork(options) {
4262
4365
  if (options.chainOpts?.network) return options.chainOpts.network;
4263
4366
  if (options.chainOpts?.blockchainRid) return void 0;
4367
+ if (this._explicitChain) return this._defaultChain.network;
4264
4368
  const orgName = options.orgName ?? this.orgName;
4265
4369
  if (!orgName) return void 0;
4266
4370
  return (await this.resolveChainForOrg(orgName)).network;
@@ -4336,6 +4440,30 @@ var Atbash = class _Atbash {
4336
4440
  return void 0;
4337
4441
  }
4338
4442
  }
4443
+ /**
4444
+ * BRID for the client's configured default org, if it has one.
4445
+ *
4446
+ * Calls that carry no `orgName` argument are not chain-less: they still
4447
+ * belong to `this.orgName`, and that org lives on exactly one chain. Routing
4448
+ * them by the constructor's chain instead means a client configured
4449
+ * `network: "private"` reads the private chain for an org that lives on
4450
+ * public, and gets an empty answer rather than an error. So where an org is
4451
+ * known the org decides the chain, and the constructor's chain is what is
4452
+ * left when no org is known at all — the order `resolveAgentLookupNetwork`
4453
+ * already applies to agent metadata reads, and the order the dashboard
4454
+ * applies in `resolveChainForWallet`.
4455
+ *
4456
+ * Undefined when there is no default org, so callers keep falling back to
4457
+ * the client default.
4458
+ */
4459
+ /** The switch's chain, unless this client named one of its own. */
4460
+ forcedNetwork() {
4461
+ return this._explicitChain ? void 0 : this._forcedNetwork;
4462
+ }
4463
+ async defaultOrgBrid() {
4464
+ if (this._explicitChain || !this.orgName) return void 0;
4465
+ return this.bridForOrg(this.orgName);
4466
+ }
4339
4467
  async raiseIfError(resp) {
4340
4468
  if (resp.ok) return;
4341
4469
  throw await this.httpError(resp);
@@ -43586,10 +43714,13 @@ function diffMemorySnapshots(before, after) {
43586
43714
  KEY_FILENAMES,
43587
43715
  MemoryGuardManager,
43588
43716
  MemoryIntegrityError,
43717
+ PRIVATE_CHAIN,
43718
+ PUBLIC_CHAIN,
43589
43719
  PointerStore,
43590
43720
  SignatureVerificationError,
43591
43721
  bootSyncFailureLine,
43592
43722
  buildAllowedJudgeHosts,
43723
+ chainForNetwork,
43593
43724
  chooseKeyPath,
43594
43725
  claimHashHex,
43595
43726
  classifyMemoryRead,