@atbash/sdk 0.10.13-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.mjs CHANGED
@@ -3311,11 +3311,36 @@ var ENV_MAP = {
3311
3311
  agentKey: "ATBASH_AGENT_KEY",
3312
3312
  orgName: "ATBASH_ORG_NAME",
3313
3313
  judgeEndpoint: "ATBASH_ENDPOINT",
3314
- blockchainRid: "ATBASH_BLOCKCHAIN_RID",
3314
+ // Same variable name the Hermes plugin already documents.
3315
+ judgeVerifyPubKey: "ATBASH_JUDGE_VERIFY_PUBKEY",
3316
+ defaultChainNetwork: "ATBASH_DEFAULT_CHAIN_NETWORK",
3315
3317
  provider: "ATBASH_PROVIDER",
3316
3318
  providerModel: "ATBASH_PROVIDER_MODEL",
3317
3319
  debug: "ATBASH_DEBUG"
3318
3320
  };
3321
+ var DEPRECATED_ENV_VARS = ["ATBASH_BLOCKCHAIN_RID"];
3322
+ var DEPRECATED_CONFIG_FIELDS = ["blockchainRid"];
3323
+ var deprecatedWarned = false;
3324
+ function warnDeprecatedEnvVarsOnce(log = console.warn) {
3325
+ if (deprecatedWarned) return;
3326
+ for (const name2 of DEPRECATED_ENV_VARS) {
3327
+ if (process.env[name2]) {
3328
+ deprecatedWarned = true;
3329
+ log(
3330
+ `[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`
3331
+ );
3332
+ }
3333
+ }
3334
+ const fileConfig = loadUserConfig();
3335
+ for (const field of DEPRECATED_CONFIG_FIELDS) {
3336
+ if (fileConfig[field]) {
3337
+ deprecatedWarned = true;
3338
+ log(
3339
+ `[atbash] "${field}" in ${getConfigPath()} is ignored \u2014 pass \`chain\` or \`network\` at construction instead`
3340
+ );
3341
+ }
3342
+ }
3343
+ }
3319
3344
  function getConfigDir() {
3320
3345
  const home2 = process.env.HOME || homedir3() || "";
3321
3346
  return join3(home2, ".config", "atbash");
@@ -3357,11 +3382,41 @@ function resolve(key3, flagValue) {
3357
3382
  if (fileVal != null) return String(fileVal);
3358
3383
  return "";
3359
3384
  }
3385
+ function forcedChainNetwork(flagValue) {
3386
+ const raw2 = resolve("defaultChainNetwork", flagValue);
3387
+ if (!raw2) return void 0;
3388
+ if (raw2 !== "public" && raw2 !== "private") {
3389
+ throw new Error(
3390
+ `ATBASH_DEFAULT_CHAIN_NETWORK / defaultChainNetwork must be "public" or "private", got ${JSON.stringify(raw2)} \u2014 unset it to let each org's chain decide.`
3391
+ );
3392
+ }
3393
+ return raw2;
3394
+ }
3360
3395
 
3361
3396
  // src-ts/client.ts
3362
3397
  function generateToolCallId() {
3363
3398
  return `tc-${Date.now()}-${randomHex(4)}`;
3364
3399
  }
3400
+ function resolveConstructorChain(options) {
3401
+ if (options.chain) return options.chain;
3402
+ const hasNodeUrls = options.nodeUrls !== void 0;
3403
+ const hasBrid = options.blockchainRid !== void 0;
3404
+ if (hasNodeUrls !== hasBrid) {
3405
+ throw new Error(
3406
+ '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"`.'
3407
+ );
3408
+ }
3409
+ if (hasNodeUrls && hasBrid) {
3410
+ const brid = options.blockchainRid;
3411
+ const derivedNetwork = options.network ?? (brid === PUBLIC_CHAIN.blockchainRid ? "public" : brid === PRIVATE_CHAIN.blockchainRid ? "private" : "private");
3412
+ return {
3413
+ network: derivedNetwork,
3414
+ blockchainRid: brid,
3415
+ nodeUrls: options.nodeUrls
3416
+ };
3417
+ }
3418
+ return chainForNetwork(options.network ?? forcedChainNetwork() ?? "private");
3419
+ }
3365
3420
  var Atbash = class _Atbash {
3366
3421
  auth;
3367
3422
  endpoint;
@@ -3385,6 +3440,27 @@ var Atbash = class _Atbash {
3385
3440
  * calls don't re-hit the dashboard. Cleared by `clearChainCache()`.
3386
3441
  */
3387
3442
  _chainCache = /* @__PURE__ */ new Map();
3443
+ /**
3444
+ * The chain the constructor settled on. Used only where a lookup returns no
3445
+ * answer — see {@link resolveChainFromMap}.
3446
+ */
3447
+ _defaultChain;
3448
+ /**
3449
+ * True when the caller named a chain outright — `chain`, `network`, or the
3450
+ * paired `blockchainRid` + `nodeUrls`.
3451
+ *
3452
+ * Such a client is never re-pointed: not by the migration switch, and not by
3453
+ * where an org turns out to live. Naming a chain is the caller saying "talk
3454
+ * to this one", and silently routing elsewhere would make the argument a
3455
+ * suggestion. A client that names nothing is the one that follows the org.
3456
+ */
3457
+ _explicitChain;
3458
+ /**
3459
+ * The fleet-wide chain switch, read once at construction. `resolve()` hits
3460
+ * the config file on disk, so re-reading it per call would put a file read
3461
+ * on every judge.
3462
+ */
3463
+ _forcedNetwork;
3388
3464
  /**
3389
3465
  * Short-TTL cache for `/api/ai/exists`. The `registered` field is
3390
3466
  * monotonic (once true, stays true), so most calls in a burst re-fetch
@@ -3409,11 +3485,23 @@ var Atbash = class _Atbash {
3409
3485
  static environmentLogged = false;
3410
3486
  constructor(privkey, options = {}) {
3411
3487
  this.auth = native.loadAgent(privkey);
3412
- this.endpoint = (options.endpoint ?? DEFAULT_ENDPOINT).replace(/\/+$/, "") || DEFAULT_ENDPOINT;
3413
- this.nodeUrls = options.nodeUrls ? [...options.nodeUrls] : DEFAULT_CHROMIA_NODE_URLS;
3414
- this.blockchainRid = options.blockchainRid ?? native.DEFAULT_BLOCKCHAIN_RID;
3488
+ const validated = validateJudgeEndpoint(
3489
+ options.verifyPubKey ? {
3490
+ policy: "self-hosted",
3491
+ endpoint: options.endpoint ?? DEFAULT_ENDPOINT,
3492
+ verifyPubKey: options.verifyPubKey
3493
+ } : { endpoint: options.endpoint }
3494
+ );
3495
+ this.endpoint = validated.url;
3496
+ const resolvedChain = resolveConstructorChain(options);
3497
+ this.nodeUrls = [...resolvedChain.nodeUrls];
3498
+ this.blockchainRid = resolvedChain.blockchainRid;
3499
+ this._defaultChain = resolvedChain;
3500
+ this._explicitChain = options.chain !== void 0 || options.network !== void 0 || options.blockchainRid !== void 0 && options.nodeUrls !== void 0;
3501
+ this._forcedNetwork = forcedChainNetwork();
3502
+ warnDeprecatedEnvVarsOnce((msg) => options.logger?.warn?.(msg));
3415
3503
  this.orgName = options.orgName;
3416
- this.verifyPubKey = options.verifyPubKey;
3504
+ this.verifyPubKey = validated.verifyPubKey ?? void 0;
3417
3505
  this.orgEncryptionPubKey = options.orgEncryptionPubKey;
3418
3506
  this.failClosed = options.failClosed !== false;
3419
3507
  this.debug = options.debug === true;
@@ -3471,15 +3559,27 @@ var Atbash = class _Atbash {
3471
3559
  * self-hosted endpoint's `verifyPubKey` becomes the client default.
3472
3560
  */
3473
3561
  static fromConfig(options = {}) {
3562
+ const configuredEndpoint = resolve("judgeEndpoint") || void 0;
3563
+ const configuredVerifyPubKey = resolve("judgeVerifyPubKey") || void 0;
3564
+ if (!options.judge && configuredVerifyPubKey && !configuredEndpoint) {
3565
+ throw new Error(
3566
+ "judgeVerifyPubKey / ATBASH_JUDGE_VERIFY_PUBKEY is set but no judge endpoint is configured: set judgeEndpoint / ATBASH_ENDPOINT to the self-hosted judge"
3567
+ );
3568
+ }
3474
3569
  const validated = validateJudgeEndpoint(
3475
- options.judge ?? { endpoint: resolve("judgeEndpoint") || void 0 }
3570
+ options.judge ?? (configuredVerifyPubKey && configuredEndpoint ? {
3571
+ policy: "self-hosted",
3572
+ endpoint: configuredEndpoint,
3573
+ verifyPubKey: configuredVerifyPubKey
3574
+ } : { endpoint: configuredEndpoint })
3476
3575
  );
3477
3576
  const agentKey = resolve("agentKey", options.agentKey);
3478
3577
  const auth = agentKey ? native.loadAgent(agentKey) : loadAgentFromFile(options.keyPath);
3479
- const blockchainRid = resolve("blockchainRid", options.blockchainRid) || void 0;
3480
3578
  return new _Atbash(auth.privkey, {
3481
3579
  endpoint: validated.url,
3482
- blockchainRid,
3580
+ chain: options.chain,
3581
+ network: options.network,
3582
+ blockchainRid: options.blockchainRid,
3483
3583
  timeoutMs: options.timeoutMs,
3484
3584
  nodeUrls: options.nodeUrls,
3485
3585
  orgName: options.orgName,
@@ -3520,7 +3620,7 @@ var Atbash = class _Atbash {
3520
3620
  return this.track("checkAgentExists", pk, async () => {
3521
3621
  const query = { pubkey: pk };
3522
3622
  if (network) query.network = network;
3523
- const brid = this.bridFromChainOpts(network ? { network } : void 0);
3623
+ const brid = network ? this.bridFromChainOpts({ network }) : await this.defaultOrgBrid();
3524
3624
  const resp = await this.http.get(
3525
3625
  "/api/ai/exists",
3526
3626
  query,
@@ -3571,7 +3671,7 @@ var Atbash = class _Atbash {
3571
3671
  };
3572
3672
  }
3573
3673
  const toolCallId = generateToolCallId();
3574
- const brid = this.bridFromChainOpts(options.chainOpts);
3674
+ const brid = options.chainOpts?.blockchainRid || options.chainOpts?.network ? this.bridFromChainOpts(options.chainOpts) : await this.defaultOrgBrid() ?? this.blockchainRid;
3575
3675
  const orgKey = options.orgEncryptionPubKey ?? this.orgEncryptionPubKey ?? this._orgKeyFromChain;
3576
3676
  try {
3577
3677
  const signedHex = orgKey ? signEncryptedToolCall(
@@ -3622,7 +3722,11 @@ var Atbash = class _Atbash {
3622
3722
  throw new Error("action is required and cannot be empty.");
3623
3723
  }
3624
3724
  let chainOpts = options.chainOpts;
3625
- if (options.orgName) {
3725
+ if (options.orgName && this._explicitChain) {
3726
+ chainOpts = options.chainOpts ?? { network: this._defaultChain.network };
3727
+ } else if (options.orgName && this.forcedNetwork()) {
3728
+ chainOpts = { network: this.forcedNetwork() };
3729
+ } else if (options.orgName) {
3626
3730
  const cached = this._chainCache.get(options.orgName);
3627
3731
  if (cached) {
3628
3732
  chainOpts = { network: cached.network };
@@ -3856,7 +3960,7 @@ var Atbash = class _Atbash {
3856
3960
  const resp = await this.http.get(
3857
3961
  "/api/v1/judge",
3858
3962
  { tool_call_id: judgmentId, agent_pubkey: pk },
3859
- this.authHeaders()
3963
+ this.authHeaders(await this.defaultOrgBrid())
3860
3964
  );
3861
3965
  await this.raiseIfError(resp);
3862
3966
  const data = await this.json(resp) ?? {};
@@ -3876,7 +3980,11 @@ var Atbash = class _Atbash {
3876
3980
  return this.track(
3877
3981
  "getToolCalls",
3878
3982
  void 0,
3879
- () => this.riskEngineRecords("tool-calls", { limit: maxCount })
3983
+ async () => this.riskEngineRecords(
3984
+ "tool-calls",
3985
+ { limit: maxCount },
3986
+ await this.defaultOrgBrid()
3987
+ )
3880
3988
  );
3881
3989
  }
3882
3990
  async getOrgToolCalls(orgName, maxCount) {
@@ -3893,24 +4001,31 @@ var Atbash = class _Atbash {
3893
4001
  return this.track(
3894
4002
  "getAgentToolCalls",
3895
4003
  agentPubkey,
3896
- () => this.riskEngineRecords("agent-tool-calls", {
3897
- agent: agentPubkey,
3898
- limit: maxCount
3899
- })
4004
+ async () => this.riskEngineRecords(
4005
+ "agent-tool-calls",
4006
+ { agent: agentPubkey, limit: maxCount },
4007
+ await this.defaultOrgBrid()
4008
+ )
3900
4009
  );
3901
4010
  }
3902
4011
  async getToolCallCount() {
3903
4012
  return this.track("getToolCallCount", void 0, async () => {
3904
- const raw2 = await this.riskEngineGet("tool-call-count", {});
4013
+ const raw2 = await this.riskEngineGet(
4014
+ "tool-call-count",
4015
+ {},
4016
+ await this.defaultOrgBrid()
4017
+ );
3905
4018
  const n = Number(raw2);
3906
4019
  return Number.isFinite(n) ? n : 0;
3907
4020
  });
3908
4021
  }
3909
4022
  async getToolCallFull(toolCallId) {
3910
4023
  return this.track("getToolCallFull", void 0, async () => {
3911
- const raw2 = await this.riskEngineGet("tool-call-full", {
3912
- tool_call_id: toolCallId
3913
- });
4024
+ const raw2 = await this.riskEngineGet(
4025
+ "tool-call-full",
4026
+ { tool_call_id: toolCallId },
4027
+ await this.defaultOrgBrid()
4028
+ );
3914
4029
  if (!isRecord(raw2)) return null;
3915
4030
  return toToolCallFull(raw2);
3916
4031
  });
@@ -3996,7 +4111,7 @@ var Atbash = class _Atbash {
3996
4111
  const resp = await this.http.get(
3997
4112
  "/api/insurance",
3998
4113
  { action: "safety-stats" },
3999
- this.authHeaders()
4114
+ this.authHeaders(await this.defaultOrgBrid())
4000
4115
  );
4001
4116
  await this.raiseIfError(resp);
4002
4117
  const data = await this.json(resp) ?? {};
@@ -4028,21 +4143,22 @@ var Atbash = class _Atbash {
4028
4143
  * entry (caller falls back to per-chain subscription resolution).
4029
4144
  */
4030
4145
  async getActiveNetworkForOrg(orgName) {
4146
+ let resp;
4031
4147
  try {
4032
- const resp = await this.http.get(
4148
+ resp = await this.http.get(
4033
4149
  "/api/org-network",
4034
- { org: orgName },
4150
+ { org: orgName.trim() },
4035
4151
  this.authHeaders()
4036
4152
  );
4037
- if (resp.status !== 200) return null;
4038
- const data = await this.json(resp);
4039
- if (data?.network === "public" || data?.network === "private") {
4040
- return data.network;
4041
- }
4042
- return null;
4043
- } catch {
4044
- return null;
4153
+ } catch (err) {
4154
+ throw this.transportError(err);
4155
+ }
4156
+ if (resp.status !== 200) throw await this.httpError(resp);
4157
+ const data = await this.json(resp);
4158
+ if (data?.network === "public" || data?.network === "private") {
4159
+ return data.network;
4045
4160
  }
4161
+ return null;
4046
4162
  }
4047
4163
  /**
4048
4164
  * Resolve which chain an org's actions should run against. Cached
@@ -4051,13 +4167,19 @@ var Atbash = class _Atbash {
4051
4167
  * 2. Per-chain subscription fallback — public + private records
4052
4168
  * are fetched in parallel, with `is_private_blockchain` and
4053
4169
  * `assigned_at` reconciling mixed states.
4054
- * Defaults to the public chain when nothing else resolves.
4170
+ * A lookup that names exactly one chain wins outright. Where it names
4171
+ * neither (a brand-new org) or cannot choose between them, the client's
4172
+ * configured default decides.
4055
4173
  */
4056
4174
  async resolveChainForOrg(orgName) {
4057
- const cached = this._chainCache.get(orgName);
4175
+ const name2 = orgName.trim();
4176
+ if (this._explicitChain) return this._defaultChain;
4177
+ const forced = this.forcedNetwork();
4178
+ if (forced) return chainForNetwork(forced);
4179
+ const cached = this._chainCache.get(name2);
4058
4180
  if (cached) return cached;
4059
- const mapNetwork = await this.getActiveNetworkForOrg(orgName);
4060
- return this.resolveChainFromMap(orgName, mapNetwork);
4181
+ const mapNetwork = await this.getActiveNetworkForOrg(name2);
4182
+ return this.resolveChainFromMap(name2, mapNetwork);
4061
4183
  }
4062
4184
  /**
4063
4185
  * Resolve a chain given an already-fetched `org_networks` map result.
@@ -4073,32 +4195,41 @@ var Atbash = class _Atbash {
4073
4195
  this._chainCache.set(orgName, chain);
4074
4196
  return chain;
4075
4197
  }
4076
- try {
4077
- const [pubSub, privSub] = await Promise.all([
4078
- this.getOrgSubscription(orgName, "public").catch(() => null),
4079
- this.getOrgSubscription(orgName, "private").catch(() => null)
4080
- ]);
4081
- if (pubSub?.is_private_blockchain) {
4082
- this._chainCache.set(orgName, PRIVATE_CHAIN);
4083
- return PRIVATE_CHAIN;
4084
- }
4085
- if (pubSub && privSub) {
4086
- const chain = privSub.assigned_at > pubSub.assigned_at ? PRIVATE_CHAIN : PUBLIC_CHAIN;
4087
- this._chainCache.set(orgName, chain);
4088
- return chain;
4089
- }
4090
- if (pubSub) {
4091
- this._chainCache.set(orgName, PUBLIC_CHAIN);
4092
- return PUBLIC_CHAIN;
4093
- }
4094
- if (privSub?.is_private_blockchain) {
4095
- this._chainCache.set(orgName, PRIVATE_CHAIN);
4096
- return PRIVATE_CHAIN;
4097
- }
4098
- } catch {
4198
+ const [pubRes, privRes] = await Promise.allSettled([
4199
+ this.getOrgSubscription(orgName, "public"),
4200
+ this.getOrgSubscription(orgName, "private")
4201
+ ]);
4202
+ const pubSub = pubRes.status === "fulfilled" ? pubRes.value : null;
4203
+ const privSub = privRes.status === "fulfilled" ? privRes.value : null;
4204
+ const failure = pubRes.status === "rejected" ? pubRes.reason : privRes.status === "rejected" ? privRes.reason : null;
4205
+ if (pubSub?.is_private_blockchain) {
4206
+ this._chainCache.set(orgName, PRIVATE_CHAIN);
4207
+ return PRIVATE_CHAIN;
4208
+ }
4209
+ if (pubSub && privSub) {
4210
+ const chain = privSub.assigned_at === pubSub.assigned_at ? this._defaultChain : privSub.assigned_at > pubSub.assigned_at ? PRIVATE_CHAIN : PUBLIC_CHAIN;
4211
+ this._chainCache.set(orgName, chain);
4212
+ return chain;
4213
+ }
4214
+ if (pubSub) {
4215
+ this._chainCache.set(orgName, PUBLIC_CHAIN);
4216
+ return PUBLIC_CHAIN;
4099
4217
  }
4100
- this._chainCache.set(orgName, PUBLIC_CHAIN);
4101
- return PUBLIC_CHAIN;
4218
+ if (privSub?.is_private_blockchain) {
4219
+ this._chainCache.set(orgName, PRIVATE_CHAIN);
4220
+ return PRIVATE_CHAIN;
4221
+ }
4222
+ if (failure) {
4223
+ const detail = failure instanceof Error ? failure.message : String(failure);
4224
+ throw new AtbashAPIError(
4225
+ failure instanceof AtbashAPIError ? failure.status : 0,
4226
+ `could not resolve the chain for org "${orgName}": ${detail}`,
4227
+ "",
4228
+ this.endpoint
4229
+ );
4230
+ }
4231
+ this._chainCache.set(orgName, this._defaultChain);
4232
+ return this._defaultChain;
4102
4233
  }
4103
4234
  /** Drop any cached chain resolutions. Useful in tests. */
4104
4235
  clearChainCache() {
@@ -4149,6 +4280,7 @@ var Atbash = class _Atbash {
4149
4280
  async resolveAgentLookupNetwork(options) {
4150
4281
  if (options.chainOpts?.network) return options.chainOpts.network;
4151
4282
  if (options.chainOpts?.blockchainRid) return void 0;
4283
+ if (this._explicitChain) return this._defaultChain.network;
4152
4284
  const orgName = options.orgName ?? this.orgName;
4153
4285
  if (!orgName) return void 0;
4154
4286
  return (await this.resolveChainForOrg(orgName)).network;
@@ -4224,6 +4356,30 @@ var Atbash = class _Atbash {
4224
4356
  return void 0;
4225
4357
  }
4226
4358
  }
4359
+ /**
4360
+ * BRID for the client's configured default org, if it has one.
4361
+ *
4362
+ * Calls that carry no `orgName` argument are not chain-less: they still
4363
+ * belong to `this.orgName`, and that org lives on exactly one chain. Routing
4364
+ * them by the constructor's chain instead means a client configured
4365
+ * `network: "private"` reads the private chain for an org that lives on
4366
+ * public, and gets an empty answer rather than an error. So where an org is
4367
+ * known the org decides the chain, and the constructor's chain is what is
4368
+ * left when no org is known at all — the order `resolveAgentLookupNetwork`
4369
+ * already applies to agent metadata reads, and the order the dashboard
4370
+ * applies in `resolveChainForWallet`.
4371
+ *
4372
+ * Undefined when there is no default org, so callers keep falling back to
4373
+ * the client default.
4374
+ */
4375
+ /** The switch's chain, unless this client named one of its own. */
4376
+ forcedNetwork() {
4377
+ return this._explicitChain ? void 0 : this._forcedNetwork;
4378
+ }
4379
+ async defaultOrgBrid() {
4380
+ if (this._explicitChain || !this.orgName) return void 0;
4381
+ return this.bridForOrg(this.orgName);
4382
+ }
4227
4383
  async raiseIfError(resp) {
4228
4384
  if (resp.ok) return;
4229
4385
  throw await this.httpError(resp);
@@ -42664,6 +42820,7 @@ async function resolveChainOptsForOrg(opts, auth) {
42664
42820
  if (opts?.orgName && !opts.chainOpts?.blockchainRid && auth) {
42665
42821
  const atbash = new Atbash(auth.privkey, {
42666
42822
  endpoint: opts.endpoint,
42823
+ verifyPubKey: opts.verifyPubKey,
42667
42824
  orgName: opts.orgName
42668
42825
  });
42669
42826
  const resolved = await atbash.resolveChainForOrg(opts.orgName);
@@ -42703,13 +42860,15 @@ function buildSigner(auth) {
42703
42860
  }
42704
42861
  async function commitMemoryVersion(plaintext, auth, opts) {
42705
42862
  const score = opts?.score ?? 5;
42863
+ const filePath = opts?.filePath ?? "";
42706
42864
  const key3 = await deriveMemoryKey(auth.privkey);
42707
42865
  const { ciphertext, nonce } = await encryptMemoryContent(plaintext, key3);
42708
42866
  const args = native.buildAddAgentMemoryArgs(
42709
42867
  auth.pubkey,
42710
42868
  ciphertext,
42711
42869
  nonce,
42712
- score
42870
+ score,
42871
+ filePath
42713
42872
  );
42714
42873
  const chainOpts = await resolveChainOptsForOrg(opts, auth);
42715
42874
  const client = await buildChainClient(chainOpts);
@@ -42721,7 +42880,8 @@ async function commitMemoryVersion(plaintext, auth, opts) {
42721
42880
  toGtxBytes(args.agent_pubkey),
42722
42881
  toGtxBytes(args.content_cipher),
42723
42882
  toGtxBytes(args.nonce),
42724
- args.score
42883
+ args.score,
42884
+ args.file_path
42725
42885
  ]
42726
42886
  },
42727
42887
  sigProvider
@@ -42743,6 +42903,7 @@ async function decryptRow(row, key3) {
42743
42903
  }
42744
42904
  return {
42745
42905
  id: parsed.id,
42906
+ filePath: parsed.file_path,
42746
42907
  content,
42747
42908
  decryptError,
42748
42909
  score: parsed.score,
@@ -42751,39 +42912,52 @@ async function decryptRow(row, key3) {
42751
42912
  updatedAt: parsed.updated_at
42752
42913
  };
42753
42914
  }
42754
- async function getActiveMemoryId(auth, chainOpts) {
42915
+ function paramsWithOptionalFilePath(agentPubkeyHex, filePath) {
42916
+ const params = {
42917
+ [native.ARG_AGENT_PUBKEY]: agentPubkeyHex
42918
+ };
42919
+ if (filePath !== null) {
42920
+ params[native.ARG_FILE_PATH] = filePath;
42921
+ }
42922
+ return params;
42923
+ }
42924
+ async function getActiveMemoryId(auth, chainOpts, filePath) {
42755
42925
  const client = await buildChainClient(chainOpts);
42756
- const q = native.buildGetActiveMemoryIdQuery(auth.pubkey);
42757
- const raw2 = await client.query(native.QUERY_GET_ACTIVE_MEMORY_ID, {
42758
- [native.ARG_AGENT_PUBKEY]: q.agent_pubkey_hex
42759
- });
42926
+ const q = native.buildGetActiveMemoryIdQuery(auth.pubkey, filePath ?? null);
42927
+ const raw2 = await client.query(
42928
+ native.QUERY_GET_ACTIVE_MEMORY_ID,
42929
+ paramsWithOptionalFilePath(q.agent_pubkey_hex, q.file_path)
42930
+ );
42760
42931
  return native.parseActiveMemoryId(raw2);
42761
42932
  }
42762
- async function getActiveMemory(auth, chainOpts) {
42933
+ async function getRecentAgentMemory(auth, chainOpts, filePath) {
42763
42934
  const client = await buildChainClient(chainOpts);
42764
42935
  const key3 = await deriveMemoryKey(auth.privkey);
42765
- const q = native.buildGetAgentMemoryQuery(auth.pubkey);
42766
- const rows = await client.query(native.QUERY_GET_AGENT_MEMORY, {
42767
- [native.ARG_AGENT_PUBKEY]: q.agent_pubkey_hex
42768
- });
42936
+ const q = native.buildGetRecentAgentMemoryQuery(auth.pubkey, filePath ?? null);
42937
+ const rows = await client.query(
42938
+ native.QUERY_GET_RECENT_AGENT_MEMORY,
42939
+ paramsWithOptionalFilePath(q.agent_pubkey_hex, q.file_path)
42940
+ );
42769
42941
  return Promise.all((rows ?? []).map((r2) => decryptRow(r2, key3)));
42770
42942
  }
42771
- async function getAllAgentMemory(auth, chainOpts) {
42943
+ async function getActiveAgentMemory(auth, chainOpts, filePath) {
42772
42944
  const client = await buildChainClient(chainOpts);
42773
42945
  const key3 = await deriveMemoryKey(auth.privkey);
42774
- const q = native.buildGetAllAgentMemoryQuery(auth.pubkey);
42775
- const rows = await client.query(native.QUERY_GET_ALL_AGENT_MEMORY, {
42776
- [native.ARG_AGENT_PUBKEY]: q.agent_pubkey_hex
42777
- });
42946
+ const q = native.buildGetActiveAgentMemoryQuery(auth.pubkey, filePath ?? null);
42947
+ const rows = await client.query(
42948
+ native.QUERY_GET_ACTIVE_AGENT_MEMORY,
42949
+ paramsWithOptionalFilePath(q.agent_pubkey_hex, q.file_path)
42950
+ );
42778
42951
  return Promise.all((rows ?? []).map((r2) => decryptRow(r2, key3)));
42779
42952
  }
42780
- async function getMemoryHistory(auth, chainOpts) {
42953
+ async function getMemoryHistory(auth, chainOpts, filePath) {
42781
42954
  const client = await buildChainClient(chainOpts);
42782
42955
  const key3 = await deriveMemoryKey(auth.privkey);
42783
- const q = native.buildGetAgentMemoryHistoryQuery(auth.pubkey);
42784
- const rows = await client.query(native.QUERY_GET_AGENT_MEMORY_HISTORY, {
42785
- [native.ARG_AGENT_PUBKEY]: q.agent_pubkey_hex
42786
- });
42956
+ const q = native.buildGetAgentMemoryHistoryQuery(auth.pubkey, filePath ?? null);
42957
+ const rows = await client.query(
42958
+ native.QUERY_GET_AGENT_MEMORY_HISTORY,
42959
+ paramsWithOptionalFilePath(q.agent_pubkey_hex, q.file_path)
42960
+ );
42787
42961
  return Promise.all((rows ?? []).map((r2) => decryptRow(r2, key3)));
42788
42962
  }
42789
42963
  async function getMemoryById(id, auth, chainOpts) {
@@ -42796,17 +42970,21 @@ async function getMemoryById(id, auth, chainOpts) {
42796
42970
  });
42797
42971
  return decryptRow(row, key3);
42798
42972
  }
42799
- async function getRollbackHistory(auth, chainOpts) {
42973
+ async function getRollbackHistory(auth, chainOpts, filePath) {
42800
42974
  const client = await buildChainClient(chainOpts);
42801
- const q = native.buildGetAgentMemoryRollbackHistoryQuery(auth.pubkey);
42975
+ const q = native.buildGetAgentMemoryRollbackHistoryQuery(
42976
+ auth.pubkey,
42977
+ filePath ?? null
42978
+ );
42802
42979
  const raw2 = await client.query(
42803
42980
  native.QUERY_GET_AGENT_MEMORY_ROLLBACK_HISTORY,
42804
- { [native.ARG_AGENT_PUBKEY]: q.agent_pubkey_hex }
42981
+ paramsWithOptionalFilePath(q.agent_pubkey_hex, q.file_path)
42805
42982
  );
42806
42983
  const parsed = native.parseRollbackRows(raw2 ?? []);
42807
42984
  return parsed.map((r2) => ({
42808
42985
  fromId: r2.from_id,
42809
42986
  toId: r2.to_id,
42987
+ filePath: r2.file_path,
42810
42988
  reason: r2.reason,
42811
42989
  signer: Buffer.from(r2.signer).toString("hex"),
42812
42990
  createdAt: r2.created_at
@@ -42874,8 +43052,7 @@ async function guardMemoryWrite(input) {
42874
43052
  toolNames,
42875
43053
  enforce = true,
42876
43054
  debug: debug2 = false,
42877
- logger: logger2,
42878
- memoryFilePath
43055
+ logger: logger2
42879
43056
  } = input;
42880
43057
  const memEntry = classifyMemoryWrite(event, ctx, { patterns, toolNames });
42881
43058
  if (debug2) emitDebugProbe(event, ctx, memEntry, logger2);
@@ -42911,37 +43088,35 @@ async function guardMemoryWrite(input) {
42911
43088
  committed: false
42912
43089
  };
42913
43090
  }
42914
- const isManagedMemoryFile = memoryFilePath !== void 0 && path3.resolve(memEntry.key) === path3.resolve(memoryFilePath);
42915
- if (isManagedMemoryFile) {
42916
- commitMemoryVersion(memEntry.value, auth, {
42917
- score: scanResult.score,
42918
- orgName,
42919
- endpoint
42920
- }).catch((err) => {
42921
- const reason = err instanceof Error ? err.message : String(err);
42922
- logger2?.warn?.("[atbash] memory commit to chain failed", {
42923
- path: memEntry.key,
42924
- reason
42925
- });
43091
+ const filePath = path3.basename(memEntry.key);
43092
+ commitMemoryVersion(memEntry.value, auth, {
43093
+ score: scanResult.score,
43094
+ filePath,
43095
+ orgName,
43096
+ endpoint,
43097
+ verifyPubKey
43098
+ }).catch((err) => {
43099
+ const reason = err instanceof Error ? err.message : String(err);
43100
+ logger2?.warn?.("[atbash] memory commit to chain failed", {
43101
+ path: memEntry.key,
43102
+ filePath,
43103
+ reason
42926
43104
  });
42927
- } else {
42928
- logger2?.info?.(
42929
- "[atbash] scanned but not committed \u2014 not the managed memory file",
42930
- {
42931
- path: memEntry.key,
42932
- memoryFilePath: memoryFilePath ?? "(not configured)"
42933
- }
42934
- );
42935
- }
43105
+ });
42936
43106
  logger2?.info?.(
42937
43107
  scanResult.verdict === "yellow" ? "[atbash] memory HOLD" : "[atbash] memory ALLOW",
42938
- { path: memEntry.key, score: scanResult.score, reason: scanResult.reason }
43108
+ {
43109
+ path: memEntry.key,
43110
+ filePath,
43111
+ score: scanResult.score,
43112
+ reason: scanResult.reason
43113
+ }
42939
43114
  );
42940
43115
  return {
42941
43116
  handled: true,
42942
43117
  decision: { allow: true },
42943
43118
  scanResult,
42944
- committed: isManagedMemoryFile
43119
+ committed: true
42945
43120
  };
42946
43121
  }
42947
43122
 
@@ -43181,9 +43356,7 @@ var MemoryGuardManager = class {
43181
43356
  toolNames: this.opts.memoryWriteToolNames,
43182
43357
  enforce: this.enforce,
43183
43358
  debug: this.opts.debug,
43184
- logger: guardLogger,
43185
- // Only this file may reach the single, path-less chain memory slot.
43186
- memoryFilePath: this.memoryFilePath
43359
+ logger: guardLogger
43187
43360
  });
43188
43361
  return this.mapGuardResult(guard);
43189
43362
  }
@@ -43456,10 +43629,13 @@ export {
43456
43629
  KEY_FILENAMES,
43457
43630
  MemoryGuardManager,
43458
43631
  MemoryIntegrityError,
43632
+ PRIVATE_CHAIN,
43633
+ PUBLIC_CHAIN,
43459
43634
  PointerStore,
43460
43635
  SignatureVerificationError,
43461
43636
  bootSyncFailureLine,
43462
43637
  buildAllowedJudgeHosts,
43638
+ chainForNetwork,
43463
43639
  chooseKeyPath,
43464
43640
  claimHashHex,
43465
43641
  classifyMemoryRead,
@@ -43483,13 +43659,13 @@ export {
43483
43659
  encryptedLength,
43484
43660
  flushTelemetry,
43485
43661
  generateKeypair,
43486
- getActiveMemory,
43662
+ getActiveAgentMemory,
43487
43663
  getActiveMemoryId,
43488
- getAllAgentMemory,
43489
43664
  getConfigDir,
43490
43665
  getConfigPath,
43491
43666
  getMemoryById,
43492
43667
  getMemoryHistory,
43668
+ getRecentAgentMemory,
43493
43669
  getRollbackHistory,
43494
43670
  guardMemoryWrite,
43495
43671
  isEnvelope,