@atbash/sdk 0.15.0-dev.0 → 0.15.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/LICENSE +202 -28
- package/NOTICE +10 -0
- package/README.md +174 -32
- package/THIRD-PARTY-NOTICES +10256 -0
- package/dist/browser.d.mts +691 -68
- package/dist/browser.mjs +1238 -602
- package/dist/index.d.mts +691 -68
- package/dist/index.d.ts +691 -68
- package/dist/index.js +3420 -43000
- package/dist/index.mjs +3315 -42928
- package/dist/testing.d.mts +15 -0
- package/dist/testing.d.ts +15 -0
- package/dist/testing.js +33 -0
- package/dist/testing.mjs +8 -0
- package/index.d.ts +21 -3
- package/index.js +66 -56
- package/package.json +27 -11
- package/dist/browser.mjs.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/index.mjs.map +0 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import nodePath from 'node:path';
|
|
2
|
+
import { Logger } from '@opentelemetry/api-logs';
|
|
3
|
+
|
|
1
4
|
type JudgeEndpointConfig = {
|
|
2
5
|
policy?: "default";
|
|
3
6
|
endpoint?: string;
|
|
@@ -28,6 +31,31 @@ interface ValidatedEndpoint {
|
|
|
28
31
|
* @internal
|
|
29
32
|
*/
|
|
30
33
|
declare function buildAllowedJudgeHosts(): ReadonlySet<string>;
|
|
34
|
+
/**
|
|
35
|
+
* Pin keys for a loopback judge, so tests can drive the pinned-host path
|
|
36
|
+
* against a local server.
|
|
37
|
+
*
|
|
38
|
+
* Only loopback hosts read this, and their traffic never leaves the machine,
|
|
39
|
+
* so it cannot loosen the check on a real Atbash host.
|
|
40
|
+
*
|
|
41
|
+
* @internal
|
|
42
|
+
* @param keys - Compressed pubkeys to pin; `[]` clears them.
|
|
43
|
+
*/
|
|
44
|
+
declare function setLoopbackJudgePinsForTests(keys: readonly string[]): void;
|
|
45
|
+
/**
|
|
46
|
+
* The keys a judge reply must be signed by, for one endpoint.
|
|
47
|
+
*
|
|
48
|
+
* An Atbash host's pinned keys always decide: a configured `verifyPubKey` on
|
|
49
|
+
* such a host must be one of them, or the client refuses to start, because a
|
|
50
|
+
* key that only had to come from config could be anyone's. A host with no pins
|
|
51
|
+
* uses the configured key, or none.
|
|
52
|
+
*
|
|
53
|
+
* @param endpoint - The validated judge endpoint URL.
|
|
54
|
+
* @param configuredKey - The `verifyPubKey` the caller configured, if any.
|
|
55
|
+
* @returns The accepted keys, current first; empty means replies are not checked.
|
|
56
|
+
* @throws When `configuredKey` is not one of the host's pinned keys.
|
|
57
|
+
*/
|
|
58
|
+
declare function judgeVerifyKeys(endpoint: string, configuredKey?: string): readonly string[];
|
|
31
59
|
declare function validateJudgeEndpoint(judge?: JudgeEndpointConfig): ValidatedEndpoint;
|
|
32
60
|
|
|
33
61
|
interface ChainConfig {
|
|
@@ -35,8 +63,12 @@ interface ChainConfig {
|
|
|
35
63
|
readonly blockchainRid: string;
|
|
36
64
|
readonly nodeUrls: readonly string[];
|
|
37
65
|
}
|
|
38
|
-
declare const PUBLIC_CHAIN: ChainConfig;
|
|
39
66
|
declare const PRIVATE_CHAIN: ChainConfig;
|
|
67
|
+
/**
|
|
68
|
+
* The chain a network name selects. Only `"private"` exists; any other value,
|
|
69
|
+
* including `"public"` from an untyped caller, is refused with the same
|
|
70
|
+
* message the config switch gives, never routed to private in silence.
|
|
71
|
+
*/
|
|
40
72
|
declare function chainForNetwork(network: Network): ChainConfig;
|
|
41
73
|
|
|
42
74
|
/**
|
|
@@ -127,23 +159,31 @@ interface MemoryScanOptions {
|
|
|
127
159
|
toolArgsJson?: string;
|
|
128
160
|
}
|
|
129
161
|
/**
|
|
130
|
-
*
|
|
131
|
-
*
|
|
132
|
-
*
|
|
133
|
-
* the org's subscription via `orgName` — callers normally don't need
|
|
134
|
-
* to pass this manually.
|
|
162
|
+
* Chain selector. Only `"private"` exists: the public testnet chains are
|
|
163
|
+
* retired. The SDK resolves an org's chain through the Dashboard via
|
|
164
|
+
* `orgName` — callers normally don't need to pass this manually.
|
|
135
165
|
*/
|
|
136
|
-
type Network = "
|
|
166
|
+
type Network = "private";
|
|
137
167
|
/**
|
|
138
168
|
* Per-call chain overrides. Pass exactly what you need to override —
|
|
139
|
-
* `network` selects between the SDK's known chains, `blockchainRid`
|
|
140
|
-
*
|
|
141
|
-
* to the SDK's defaults (or to org-resolved
|
|
169
|
+
* `network` selects between the SDK's known chains, `blockchainRid` pins a
|
|
170
|
+
* custom one, and `endpoint` names the Dashboard the calls travel over. Pass
|
|
171
|
+
* none of these to fall back to the SDK's defaults (or to the org-resolved
|
|
172
|
+
* chain when `orgName` is set).
|
|
142
173
|
*/
|
|
143
174
|
interface ChainOpts {
|
|
144
175
|
network?: Network;
|
|
145
176
|
blockchainRid?: string;
|
|
177
|
+
/**
|
|
178
|
+
* No longer dialled: memory reaches the chain through the Dashboard. Kept
|
|
179
|
+
* because callers and the other bindings still carry it as chain config.
|
|
180
|
+
*/
|
|
146
181
|
nodeUrls?: readonly string[];
|
|
182
|
+
/**
|
|
183
|
+
* Dashboard base URL. Memory reaches the chain through it, so this is where
|
|
184
|
+
* those requests go; defaults to the endpoint compiled into the core.
|
|
185
|
+
*/
|
|
186
|
+
endpoint?: string;
|
|
147
187
|
}
|
|
148
188
|
/** Canonical verdict after normalization. */
|
|
149
189
|
type Verdict = "ALLOW" | "HOLD" | "BLOCK" | "No verdict";
|
|
@@ -180,13 +220,23 @@ interface JudgeResult {
|
|
|
180
220
|
provider: string;
|
|
181
221
|
latencyMs: number;
|
|
182
222
|
toolCallId: string;
|
|
223
|
+
/**
|
|
224
|
+
* The id the judge recorded this verdict under, when it differs from
|
|
225
|
+
* `toolCallId` (the on-chain judge path). Poll `getJudgmentStatus` with
|
|
226
|
+
* `judgmentId || toolCallId`. Absent when the reply names none.
|
|
227
|
+
*/
|
|
228
|
+
judgmentId?: string;
|
|
183
229
|
onChain: boolean;
|
|
230
|
+
/** What the reply stated about the chain; see {@link VerdictRecord}. */
|
|
231
|
+
record?: VerdictRecord;
|
|
184
232
|
/** Severity 1 (poisonous) → 10 (benign). Present on memory-scan responses; absent for regular tool-call judgments. */
|
|
185
233
|
score?: number;
|
|
186
234
|
/**
|
|
187
235
|
* Whether the org's protection mode actually acts on a HOLD/BLOCK verdict.
|
|
188
236
|
* `false` in Monitor mode (verdict is logged for observation, agent is NOT
|
|
189
237
|
* jailed and the action is not held); `true` in Enforce mode.
|
|
238
|
+
* A plain boolean: an omitted field reads as `false`. `Decision.enforced`
|
|
239
|
+
* keeps "unknown" apart; gate on that, not on this.
|
|
190
240
|
*/
|
|
191
241
|
enforced: boolean;
|
|
192
242
|
/** Server-reported protection mode: `off`, `monitor`, or `enforce`. */
|
|
@@ -198,6 +248,11 @@ interface JudgeResult {
|
|
|
198
248
|
* missing" — never infer the former from a null verdict alone.
|
|
199
249
|
*/
|
|
200
250
|
status: string;
|
|
251
|
+
/**
|
|
252
|
+
* The judge's explicit refusal in the raw body (`explicitRefusal`): "BLOCK",
|
|
253
|
+
* "HOLD", or "" when it neither refused nor is a known refusal shape.
|
|
254
|
+
*/
|
|
255
|
+
refusal?: "" | "BLOCK" | "HOLD";
|
|
201
256
|
}
|
|
202
257
|
interface JudgmentStatus {
|
|
203
258
|
status: JudgmentState;
|
|
@@ -209,6 +264,12 @@ interface JudgmentStatus {
|
|
|
209
264
|
onChain?: boolean;
|
|
210
265
|
cached?: boolean;
|
|
211
266
|
responseTimeMs?: number;
|
|
267
|
+
/**
|
|
268
|
+
* The verdict the judge reached (`"BLOCK"` or `"HOLD"`) when the
|
|
269
|
+
* organisation's signed mode (`shadow`, `monitor`, `off`) let the action run
|
|
270
|
+
* anyway, as {@link Decision.wouldVerdict}. Absent when the status is the verdict.
|
|
271
|
+
*/
|
|
272
|
+
wouldVerdict?: "BLOCK" | "HOLD";
|
|
212
273
|
}
|
|
213
274
|
interface TierInfo {
|
|
214
275
|
orgName: string;
|
|
@@ -305,6 +366,13 @@ interface AtbashLogger {
|
|
|
305
366
|
/** Options accepted by the `Atbash` constructor. */
|
|
306
367
|
interface AtbashOptions {
|
|
307
368
|
endpoint?: string;
|
|
369
|
+
/**
|
|
370
|
+
* Overall deadline for one `auditToolCall` decision, across every request
|
|
371
|
+
* it makes (org lookup, exists check, judge). Default 60 000 ms. When it
|
|
372
|
+
* passes the decision is an ERROR (denied unless `failClosed` is false).
|
|
373
|
+
* `timeoutMs` still bounds each single request.
|
|
374
|
+
*/
|
|
375
|
+
decisionTimeoutMs?: number;
|
|
308
376
|
timeoutMs?: number;
|
|
309
377
|
/**
|
|
310
378
|
* Full chain override — BRID + nodeUrls in one object. Wins over every
|
|
@@ -313,7 +381,7 @@ interface AtbashOptions {
|
|
|
313
381
|
*/
|
|
314
382
|
chain?: ChainConfig;
|
|
315
383
|
/**
|
|
316
|
-
* Preset chain selector — `"
|
|
384
|
+
* Preset chain selector — `"private"` is the only value. Resolves to the
|
|
317
385
|
* matching `ChainConfig` via `chainForNetwork()`. Overridden by `chain`,
|
|
318
386
|
* overrides env `ATBASH_DEFAULT_CHAIN_NETWORK` and the config file.
|
|
319
387
|
*/
|
|
@@ -348,8 +416,35 @@ interface AtbashOptions {
|
|
|
348
416
|
* `orgEncryptionPubKey` overrides this, same as `verifyPubKey`.
|
|
349
417
|
*/
|
|
350
418
|
orgEncryptionPubKey?: string;
|
|
351
|
-
/**
|
|
419
|
+
/**
|
|
420
|
+
* When true (default), `auditToolCall` denies on any error. When false, it
|
|
421
|
+
* allows only when Atbash could not be reached or could not answer: a
|
|
422
|
+
* transport failure, a timeout, a 5xx or a 408 (and a readable reply that
|
|
423
|
+
* neither grants nor refuses). Atbash's own refusals still deny: an
|
|
424
|
+
* unregistered agent, any other 4xx (no policy, billing suspended, quota
|
|
425
|
+
* exhausted or rate limited, unauthorized), and a 2xx reply that is not a
|
|
426
|
+
* JSON object. Direct `judgeAction` callers get a `JudgeRefusalError` for
|
|
427
|
+
* an unregistered agent or an unreadable reply.
|
|
428
|
+
*/
|
|
352
429
|
failClosed?: boolean;
|
|
430
|
+
/**
|
|
431
|
+
* When true (the default), an answer that carries no enforcement decision
|
|
432
|
+
* (the audit tier's `{status:"logged"}` with no verdict) is refused:
|
|
433
|
+
* `auditToolCall` returns `{allow:false, verdict:"ERROR"}` whatever
|
|
434
|
+
* `failClosed` says, and `judgeAction().allow` / `getJudgmentStatus().allow`
|
|
435
|
+
* are false. Set it to `false` only to run deliberately in log-only mode
|
|
436
|
+
* (security review 2026-09-30, H6: an unsigned marker switched enforcement
|
|
437
|
+
* off).
|
|
438
|
+
*/
|
|
439
|
+
requireEnforcement?: boolean;
|
|
440
|
+
/**
|
|
441
|
+
* When true, `auditToolCall` enforces the judge's verdict whatever
|
|
442
|
+
* enforcement mode the organisation is in. Default false: on a judge host
|
|
443
|
+
* whose replies are signature-checked, a signed `shadow`, `monitor` or `off`
|
|
444
|
+
* mode lets a BLOCK or HOLD run, reported in `Decision.wouldVerdict`. This
|
|
445
|
+
* can only make the client stricter.
|
|
446
|
+
*/
|
|
447
|
+
enforceLocally?: boolean;
|
|
353
448
|
/**
|
|
354
449
|
* Verbose diagnostics. Off by default. When on, a failed judge call also
|
|
355
450
|
* logs the response body, which is the difference between "judge API failed"
|
|
@@ -358,6 +453,44 @@ interface AtbashOptions {
|
|
|
358
453
|
debug?: boolean;
|
|
359
454
|
logger?: AtbashLogger;
|
|
360
455
|
}
|
|
456
|
+
/**
|
|
457
|
+
* What the judge stated about recording this verdict. A host that must not run
|
|
458
|
+
* an unrecorded action gates on `verdictRecorded`. `onChain` is the judge's
|
|
459
|
+
* statement: the SDK does not read the chain.
|
|
460
|
+
*/
|
|
461
|
+
interface VerdictRecord {
|
|
462
|
+
/** The judge's `on_chain`: the verdict is recorded on chain. */
|
|
463
|
+
onChain: boolean;
|
|
464
|
+
/** The judge's `on_chain_status`, such as `pending` or `skipped`; absent when not stated. */
|
|
465
|
+
status?: string;
|
|
466
|
+
/**
|
|
467
|
+
* The reply names the ids this call generated. False when it names another
|
|
468
|
+
* call, or none: `toolCallId` then falls back to this client's own id, which
|
|
469
|
+
* proves nothing about what the judge recorded.
|
|
470
|
+
*/
|
|
471
|
+
boundToCall: boolean;
|
|
472
|
+
/**
|
|
473
|
+
* This reply's signature was checked against a judge key before it was read.
|
|
474
|
+
* False means nothing proves who wrote the reply: it can echo this call's ids
|
|
475
|
+
* and still read as bound, because the ids travel in the request.
|
|
476
|
+
*/
|
|
477
|
+
signatureChecked: boolean;
|
|
478
|
+
/**
|
|
479
|
+
* The judge's own `status`, absent when not stated. `shadow_recorded` is a
|
|
480
|
+
* shadow ack: the call was stored and has no verdict yet, which is what
|
|
481
|
+
* separates it from an ALLOW whose `status` here is `pending`. Read it with
|
|
482
|
+
* `boundToCall` and `signatureChecked`: unsigned, it is only a claim.
|
|
483
|
+
*/
|
|
484
|
+
judgeStatus?: string;
|
|
485
|
+
/**
|
|
486
|
+
* The judge answered this call with a verdict it states is recorded on chain,
|
|
487
|
+
* in a signature-checked reply: `onChain`, `boundToCall` and `signatureChecked`
|
|
488
|
+
* all true, and no `judgeStatus`, which only a reply without a verdict carries
|
|
489
|
+
* (a shadow ack, or an answer that was only logged). Still the judge's word:
|
|
490
|
+
* the SDK does not read the chain.
|
|
491
|
+
*/
|
|
492
|
+
verdictRecorded: boolean;
|
|
493
|
+
}
|
|
361
494
|
/** Canonical decision returned by `auditToolCall`. */
|
|
362
495
|
type DecisionVerdict = "ALLOW" | "HOLD" | "BLOCK" | "ERROR";
|
|
363
496
|
interface Decision {
|
|
@@ -365,6 +498,34 @@ interface Decision {
|
|
|
365
498
|
verdict: DecisionVerdict;
|
|
366
499
|
reason?: string;
|
|
367
500
|
toolCallId?: string;
|
|
501
|
+
/**
|
|
502
|
+
* Whether the organisation acts on a HOLD/BLOCK verdict; false under Monitor mode and per-agent Shadow Mode. Absent means unknown: a
|
|
503
|
+
* transport error, or a judge that stated no mode. Test `=== false`, never
|
|
504
|
+
* `!decision.enforced`, or every outage counts as a would-block.
|
|
505
|
+
* Informational only; `allow` remains the gate.
|
|
506
|
+
*/
|
|
507
|
+
enforced?: boolean;
|
|
508
|
+
/** Server-reported protection mode (`off`, `monitor`, `enforce`); absent when unknown. */
|
|
509
|
+
enforcementMode?: string;
|
|
510
|
+
/**
|
|
511
|
+
* The verdict the judge reached when the organisation's signed mode
|
|
512
|
+
* (`shadow`, `monitor`, `off`) let the action run anyway: what would have
|
|
513
|
+
* happened under enforcement. Absent when the decision is the verdict.
|
|
514
|
+
*/
|
|
515
|
+
wouldVerdict?: "BLOCK" | "HOLD";
|
|
516
|
+
/**
|
|
517
|
+
* The id the judge recorded this verdict under, when it differs from
|
|
518
|
+
* `toolCallId` (the on-chain judge path), as {@link JudgeResult.judgmentId}.
|
|
519
|
+
* Poll `getJudgmentStatus` with `judgmentId || toolCallId`.
|
|
520
|
+
*/
|
|
521
|
+
judgmentId?: string;
|
|
522
|
+
/**
|
|
523
|
+
* What the judge stated about recording this verdict. Absent means unknown:
|
|
524
|
+
* a transport error, a local jail hold, or a reply that did not state
|
|
525
|
+
* `on_chain`. Treat absent as not recorded. Informational only; `allow`
|
|
526
|
+
* remains the gate.
|
|
527
|
+
*/
|
|
528
|
+
record?: VerdictRecord;
|
|
368
529
|
}
|
|
369
530
|
/** Input to `auditToolCall`. */
|
|
370
531
|
interface ToolCallInput {
|
|
@@ -400,6 +561,12 @@ interface FromConfigOptions {
|
|
|
400
561
|
/** Default org name — see {@link AtbashOptions.orgName}. */
|
|
401
562
|
orgName?: string;
|
|
402
563
|
failClosed?: boolean;
|
|
564
|
+
/** See {@link AtbashOptions.requireEnforcement}. Default true. */
|
|
565
|
+
requireEnforcement?: boolean;
|
|
566
|
+
/** See {@link AtbashOptions.enforceLocally}. Default false. */
|
|
567
|
+
enforceLocally?: boolean;
|
|
568
|
+
/** See {@link AtbashOptions.decisionTimeoutMs}. Default 60 000 ms. */
|
|
569
|
+
decisionTimeoutMs?: number;
|
|
403
570
|
/** See {@link AtbashOptions.debug}. */
|
|
404
571
|
debug?: boolean;
|
|
405
572
|
logger?: AtbashLogger;
|
|
@@ -408,8 +575,6 @@ interface FromConfigOptions {
|
|
|
408
575
|
interface JudgeOptions {
|
|
409
576
|
toolName?: string;
|
|
410
577
|
toolArgsJson?: string;
|
|
411
|
-
provider?: string;
|
|
412
|
-
model?: string;
|
|
413
578
|
verifyPubKey?: string;
|
|
414
579
|
/** Per-call override of {@link AtbashOptions.orgEncryptionPubKey}. */
|
|
415
580
|
orgEncryptionPubKey?: string;
|
|
@@ -454,10 +619,23 @@ declare class Atbash {
|
|
|
454
619
|
readonly orgName?: string;
|
|
455
620
|
/** Default judge response-signing pubkey, if configured (see fromConfig). */
|
|
456
621
|
readonly verifyPubKey?: string;
|
|
622
|
+
/**
|
|
623
|
+
* The keys every judge reply must be signed by: the host's pinned keys, or
|
|
624
|
+
* the configured `verifyPubKey` on a host with none. Empty means unchecked.
|
|
625
|
+
*/
|
|
626
|
+
private readonly verifyKeys;
|
|
457
627
|
/** Default org encryption key — see {@link AtbashOptions.orgEncryptionPubKey}. */
|
|
458
628
|
readonly orgEncryptionPubKey?: string;
|
|
459
629
|
/** When true (default), `auditToolCall` denies on any error. */
|
|
460
630
|
readonly failClosed: boolean;
|
|
631
|
+
/** When true (default), an unenforced (audit-tier) answer is refused. */
|
|
632
|
+
readonly requireEnforcement: boolean;
|
|
633
|
+
/** When true, a signed non-enforcing mode never relaxes a verdict. */
|
|
634
|
+
readonly enforceLocally: boolean;
|
|
635
|
+
/** Results whose enforcement mode came signed and bound to their call. */
|
|
636
|
+
private readonly modeTrusted;
|
|
637
|
+
/** Overall deadline for one auditToolCall decision, in ms. */
|
|
638
|
+
readonly decisionTimeoutMs: number;
|
|
461
639
|
/** Org key learned from the last agent-exists check, for this agent only. */
|
|
462
640
|
private _orgKeyFromChain;
|
|
463
641
|
private readonly debug;
|
|
@@ -499,12 +677,6 @@ declare class Atbash {
|
|
|
499
677
|
*/
|
|
500
678
|
private _agentExistsCache;
|
|
501
679
|
private static readonly AGENT_EXISTS_TTL_MS;
|
|
502
|
-
/**
|
|
503
|
-
* Cached bearer token for risk-engine / insurance read calls. Built
|
|
504
|
-
* lazily as a signed `log_tool_call` tx and refreshed every 4 min so
|
|
505
|
-
* server-side replay protection windows never expire it mid-session.
|
|
506
|
-
*/
|
|
507
|
-
private _authBearers;
|
|
508
680
|
/** Guards `logEnvironmentOnce` — hosts construct several clients. */
|
|
509
681
|
private static environmentLogged;
|
|
510
682
|
constructor(privkey: string, options?: AtbashOptions);
|
|
@@ -527,6 +699,48 @@ declare class Atbash {
|
|
|
527
699
|
* validated against the trusted allowlist / self-hosted policy; a
|
|
528
700
|
* self-hosted endpoint's `verifyPubKey` becomes the client default.
|
|
529
701
|
*/
|
|
702
|
+
/**
|
|
703
|
+
* Decide which key this client signs as.
|
|
704
|
+
*
|
|
705
|
+
* Most specific wins: a key passed in code, then a key file the host named,
|
|
706
|
+
* then the environment, then the default key file. `config.json` is absent
|
|
707
|
+
* from that list on purpose — it is a settings file, writable by anything
|
|
708
|
+
* that can write the user's home and read by every Atbash integration on the
|
|
709
|
+
* machine, so letting it name the key meant one stray value silently
|
|
710
|
+
* re-pointed who each of them signed as.
|
|
711
|
+
*
|
|
712
|
+
* A named `keyPath` that does not exist throws rather than falling through.
|
|
713
|
+
* The caller said which file holds its identity; quietly signing as a
|
|
714
|
+
* different one is the outcome worth refusing.
|
|
715
|
+
*
|
|
716
|
+
* @param options - The `fromConfig` options, read for `agentKey` and `keyPath`.
|
|
717
|
+
* @returns The resolved agent identity.
|
|
718
|
+
* @throws When a named key file is missing, or no identity can be found.
|
|
719
|
+
*/
|
|
720
|
+
private static resolveIdentity;
|
|
721
|
+
/**
|
|
722
|
+
* Add the one thing a machine with no key file needs to hear.
|
|
723
|
+
*
|
|
724
|
+
* This is the only path where the operator cannot see what happened: no key
|
|
725
|
+
* file, and the key they are looking for sits in `config.json`, which no
|
|
726
|
+
* longer selects the identity. A bare "key file not found" sends them hunting
|
|
727
|
+
* for a key they already have. Only this branch gets the hint — a caller who
|
|
728
|
+
* named a `keyPath` is told about that path, where a stranded key is noise.
|
|
729
|
+
*
|
|
730
|
+
* @param err - The "key file not found" error from the default lookup.
|
|
731
|
+
* @returns The same error, or one that also names the key in config.json.
|
|
732
|
+
*/
|
|
733
|
+
private static explainStrandedKey;
|
|
734
|
+
/**
|
|
735
|
+
* Say so when `config.json` still holds an agent key.
|
|
736
|
+
*
|
|
737
|
+
* Nothing signs with it any more, and silence would leave an operator
|
|
738
|
+
* believing one identity is in force while another is. The pubkey is named,
|
|
739
|
+
* not the key, so the line is safe in a log.
|
|
740
|
+
*
|
|
741
|
+
* @param logger - The host logger, when one was supplied.
|
|
742
|
+
*/
|
|
743
|
+
private static warnOnStrandedKey;
|
|
530
744
|
static fromConfig(options?: FromConfigOptions): Atbash;
|
|
531
745
|
get pubkey(): string;
|
|
532
746
|
get privkey(): string;
|
|
@@ -546,6 +760,13 @@ declare class Atbash {
|
|
|
546
760
|
* return the signed tx hex. The server broadcasts to chain.
|
|
547
761
|
*/
|
|
548
762
|
logToolCall(action: string, context?: string, options?: LogToolCallOptions): Promise<LogToolCallResult>;
|
|
763
|
+
/**
|
|
764
|
+
* `raisePreflightErrors` (the judge path, like Python's
|
|
765
|
+
* `raise_preflight_errors`): a failed registration check throws instead of
|
|
766
|
+
* becoming `{ success: false }`, so the caller can tell Atbash's "no"
|
|
767
|
+
* (not registered, or a 4xx) from an outage.
|
|
768
|
+
*/
|
|
769
|
+
private _logToolCall;
|
|
549
770
|
/**
|
|
550
771
|
* Sign log_tool_call + optionally judge_action, POST /api/v1/judge.
|
|
551
772
|
*
|
|
@@ -553,7 +774,29 @@ declare class Atbash {
|
|
|
553
774
|
* response bytes via the Rust core's `verifySignature`.
|
|
554
775
|
*/
|
|
555
776
|
judgeAction(action: string, context?: string, options?: JudgeOptions): Promise<JudgeResult>;
|
|
777
|
+
/**
|
|
778
|
+
* judgeAction, optionally asking the judge for the true verdict and the
|
|
779
|
+
* organisation's enforcement mode so this client applies the mode itself.
|
|
780
|
+
*
|
|
781
|
+
* Only auditToolCall opts in: judgeAction's callers keep the server-side
|
|
782
|
+
* downgrade they gate on today.
|
|
783
|
+
*
|
|
784
|
+
* @param clientEnforces - Send `X-Atbash-Client-Enforcement` when the reply can be trusted.
|
|
785
|
+
*/
|
|
786
|
+
private judgeTracked;
|
|
556
787
|
private _judgeAction;
|
|
788
|
+
/**
|
|
789
|
+
* Start a local hold on an enforced BLOCK that jails: one already on chain,
|
|
790
|
+
* or one the judge answered before its chain write landed
|
|
791
|
+
* (`on_chain_status: "pending"`), which jails once it lands. Refuse any other
|
|
792
|
+
* result that lands while the agent is held, or whose request was already in
|
|
793
|
+
* flight when the block arrived: the server judged it on pre-jail state.
|
|
794
|
+
*
|
|
795
|
+
* @param onChainStatus - The reply's `on_chain_status`; empty when absent.
|
|
796
|
+
*/
|
|
797
|
+
private applyJailHold;
|
|
798
|
+
/** The server's jailed refusal, produced locally while the agent is held. */
|
|
799
|
+
private localJailBlock;
|
|
557
800
|
/**
|
|
558
801
|
* High-level guard: redact secrets, submit for judgement, and collapse the
|
|
559
802
|
* result into an allow/deny `Decision`. Fails closed by default — any error
|
|
@@ -561,6 +804,33 @@ declare class Atbash {
|
|
|
561
804
|
* explicitly false.
|
|
562
805
|
*/
|
|
563
806
|
auditToolCall(input: ToolCallInput): Promise<Decision>;
|
|
807
|
+
/**
|
|
808
|
+
* The verify keys for one call (R4, governor tier-2 review). A per-call key
|
|
809
|
+
* may only narrow what the client accepts: on a client pinned to judge keys
|
|
810
|
+
* it must be one of them, never a replacement; on an unpinned client it
|
|
811
|
+
* adds the check.
|
|
812
|
+
*/
|
|
813
|
+
private effectiveVerifyKeys;
|
|
814
|
+
/**
|
|
815
|
+
* Collapse a judge result into a {@link Decision}. The most restrictive
|
|
816
|
+
* signal wins (security review 2026-09-30, H1): `action_type`, `verdict`
|
|
817
|
+
* and the canonical `allow` are each able to deny, and only a result where
|
|
818
|
+
* all three agree may execute. A present `allow` / `decision.allow` that is
|
|
819
|
+
* not exactly `true` is the judge declining to grant permission, so it
|
|
820
|
+
* denies even under `failClosed: false` — that option relaxes *errors*, it
|
|
821
|
+
* never overrides a refusal.
|
|
822
|
+
*/
|
|
823
|
+
private decide;
|
|
824
|
+
/**
|
|
825
|
+
* Apply the organisation's enforcement mode to the judge's true verdict.
|
|
826
|
+
*
|
|
827
|
+
* Only a mode that arrived signed and bound to this call counts; a missing,
|
|
828
|
+
* unsigned or unknown mode, or enforceLocally, means enforce. Under
|
|
829
|
+
* `shadow`, `monitor` or `off` a BLOCK or HOLD runs, reported in
|
|
830
|
+
* `wouldVerdict`. An ERROR stays an error: it is not a verdict.
|
|
831
|
+
*/
|
|
832
|
+
private applyMode;
|
|
833
|
+
private decideInner;
|
|
564
834
|
/**
|
|
565
835
|
* One exit for every judge failure.
|
|
566
836
|
*
|
|
@@ -570,16 +840,22 @@ declare class Atbash {
|
|
|
570
840
|
* The response body follows only under `debug`, since it can echo the action.
|
|
571
841
|
*/
|
|
572
842
|
private failJudge;
|
|
843
|
+
/**
|
|
844
|
+
* The canonical permission for a response body under this client's
|
|
845
|
+
* settings: {@link canonicalAllow}, minus the audit tier when
|
|
846
|
+
* `requireEnforcement` is on. Never more permissive than `auditToolCall`.
|
|
847
|
+
*/
|
|
848
|
+
private executable;
|
|
573
849
|
private fail;
|
|
574
850
|
/**
|
|
575
851
|
* Return the current status of a previously submitted judgment.
|
|
576
852
|
*
|
|
577
|
-
* `chainOpts` names which chain the judgment was signed against
|
|
578
|
-
*
|
|
579
|
-
*
|
|
580
|
-
*
|
|
581
|
-
*
|
|
582
|
-
*
|
|
853
|
+
* `chainOpts` names which chain the judgment was signed against; the SDK
|
|
854
|
+
* sends it as the `brid` query param the server routes by. Without it the
|
|
855
|
+
* read uses the same chain `judgeAction` signs for (see `callBrid`): the
|
|
856
|
+
* client's org chain when it has an `orgName`, else the client default.
|
|
857
|
+
* A judgment signed with an explicit per-call `chainOpts` (or a per-call
|
|
858
|
+
* `orgName` on another chain) must be polled with that same `chainOpts`.
|
|
583
859
|
*/
|
|
584
860
|
getJudgmentStatus(judgmentId: string, agentPubkey?: string, chainOpts?: ChainOpts): Promise<JudgmentStatus>;
|
|
585
861
|
getToolCalls(maxCount: number): Promise<ToolCallRecord[]>;
|
|
@@ -611,12 +887,9 @@ declare class Atbash {
|
|
|
611
887
|
* Resolve which chain an org's actions should run against. Cached
|
|
612
888
|
* per-client by orgName. Resolution order:
|
|
613
889
|
* 1. `org_networks` map (authoritative).
|
|
614
|
-
* 2.
|
|
615
|
-
*
|
|
616
|
-
*
|
|
617
|
-
* A lookup that names exactly one chain wins outright. Where it names
|
|
618
|
-
* neither (a brand-new org) or cannot choose between them, the client's
|
|
619
|
-
* configured default decides.
|
|
890
|
+
* 2. Subscription fallback — the org's subscription row on the chain.
|
|
891
|
+
* A lookup that finds the org wins outright. Where it finds nothing (a
|
|
892
|
+
* brand-new org), the client's configured default decides.
|
|
620
893
|
*/
|
|
621
894
|
resolveChainForOrg(orgName: string): Promise<ChainConfig>;
|
|
622
895
|
/**
|
|
@@ -644,6 +917,13 @@ declare class Atbash {
|
|
|
644
917
|
* chains; otherwise the client's default.
|
|
645
918
|
*/
|
|
646
919
|
private bridFromChainOpts;
|
|
920
|
+
/**
|
|
921
|
+
* The chain one call's transactions are signed for: the per-call override
|
|
922
|
+
* when given, otherwise the client's org, otherwise the client default.
|
|
923
|
+
* log_tool_call, judge_action and the judgment-status read all use this, so
|
|
924
|
+
* a request never pairs transactions signed for two different chains.
|
|
925
|
+
*/
|
|
926
|
+
private callBrid;
|
|
647
927
|
/**
|
|
648
928
|
* Resolve the dashboard chain used by agent metadata/policy reads.
|
|
649
929
|
* Explicit per-call network overrides win; otherwise use the supplied org
|
|
@@ -714,20 +994,48 @@ declare class Atbash {
|
|
|
714
994
|
static containsEvasionCharacters(text: string): boolean;
|
|
715
995
|
}
|
|
716
996
|
|
|
997
|
+
declare const DEFAULTS: {
|
|
998
|
+
ceilingMs: number;
|
|
999
|
+
pollMs: number;
|
|
1000
|
+
};
|
|
1001
|
+
/** Whether `pubkey` is currently held. */
|
|
1002
|
+
declare function isJailHeld(pubkey: string): boolean;
|
|
1003
|
+
/** Forget every hold and stop its poll; tests and hosts that reset state. */
|
|
1004
|
+
declare function releaseJailHolds(): void;
|
|
1005
|
+
/** Override the ceiling or poll interval; an empty object restores defaults. */
|
|
1006
|
+
declare function configureJailHold(next: Partial<typeof DEFAULTS>): void;
|
|
1007
|
+
|
|
717
1008
|
declare const DEFAULT_ENDPOINT: string;
|
|
718
|
-
declare const DEFAULT_CHROMIA_NODE_URLS: readonly string[];
|
|
719
|
-
declare const DEFAULT_BLOCKCHAIN_RID: string;
|
|
720
1009
|
|
|
721
1010
|
declare class AtbashAPIError extends Error {
|
|
722
1011
|
/** HTTP status code (or 0 if the request never completed). */
|
|
723
1012
|
readonly status: number;
|
|
724
1013
|
/** Raw response body text (may be empty). */
|
|
725
1014
|
readonly body: string;
|
|
726
|
-
|
|
1015
|
+
/**
|
|
1016
|
+
* Request path this status came from, e.g. `/api/v1/judge` — absent when the
|
|
1017
|
+
* request never reached a response (transport failures carry status 0).
|
|
1018
|
+
*
|
|
1019
|
+
* A status alone does not say what failed. Several routes answer one call, and
|
|
1020
|
+
* more than one of them can 404: a caller reading only `404` cannot tell "this
|
|
1021
|
+
* agent is not registered" from "the chain-routing lookup did not resolve", and
|
|
1022
|
+
* has to guess from the body's prose — which a 404 raised before any handler
|
|
1023
|
+
* ran does not carry. The path is the fact that settles it.
|
|
1024
|
+
*/
|
|
1025
|
+
readonly path?: string;
|
|
1026
|
+
constructor(status: number, body: string, statusText?: string, endpoint?: string, path?: string);
|
|
727
1027
|
}
|
|
728
1028
|
declare class SignatureVerificationError extends Error {
|
|
729
1029
|
constructor(message: string);
|
|
730
1030
|
}
|
|
1031
|
+
/**
|
|
1032
|
+
* Atbash answered, and the answer was not a grant: the agent is not
|
|
1033
|
+
* registered, or the reply could not be read. Unlike an unreachable judge this
|
|
1034
|
+
* always denies, whatever `failClosed` says.
|
|
1035
|
+
*/
|
|
1036
|
+
declare class JudgeRefusalError extends Error {
|
|
1037
|
+
constructor(message: string);
|
|
1038
|
+
}
|
|
731
1039
|
|
|
732
1040
|
/**
|
|
733
1041
|
* Thin typed fetch wrapper.
|
|
@@ -807,8 +1115,6 @@ interface AtbashUserConfig {
|
|
|
807
1115
|
* at construction instead.
|
|
808
1116
|
*/
|
|
809
1117
|
defaultChainNetwork?: Network;
|
|
810
|
-
provider?: string;
|
|
811
|
-
providerModel?: string;
|
|
812
1118
|
/** "1" / "true" turns on verbose diagnostics. See AtbashOptions.debug. */
|
|
813
1119
|
debug?: string;
|
|
814
1120
|
}
|
|
@@ -917,7 +1223,7 @@ interface CommitMemoryOptions {
|
|
|
917
1223
|
filePath?: string;
|
|
918
1224
|
/** Org name — when set, the SDK resolves which chain the agent lives on. */
|
|
919
1225
|
orgName?: string;
|
|
920
|
-
/** Atbash service endpoint
|
|
1226
|
+
/** Atbash service endpoint — where memory reaches the chain, and the org→chain lookup. */
|
|
921
1227
|
endpoint?: string;
|
|
922
1228
|
/** Self-hosted judge response-signing pubkey; required with a non-allowlisted `endpoint`. */
|
|
923
1229
|
verifyPubKey?: string;
|
|
@@ -925,6 +1231,7 @@ interface CommitMemoryOptions {
|
|
|
925
1231
|
}
|
|
926
1232
|
interface RollbackMemoryOptions {
|
|
927
1233
|
orgName?: string;
|
|
1234
|
+
/** Atbash service endpoint — where memory reaches the chain, and the org→chain lookup. */
|
|
928
1235
|
endpoint?: string;
|
|
929
1236
|
/** Self-hosted judge response-signing pubkey; required with a non-allowlisted `endpoint`. */
|
|
930
1237
|
verifyPubKey?: string;
|
|
@@ -984,11 +1291,18 @@ declare function getRecentAgentMemory(auth: AgentAuth, chainOpts?: ChainOpts, fi
|
|
|
984
1291
|
* when you need every active version regardless of age.
|
|
985
1292
|
*/
|
|
986
1293
|
declare function getActiveAgentMemory(auth: AgentAuth, chainOpts?: ChainOpts, filePath?: string | null): Promise<AgentMemoryEntry[]>;
|
|
1294
|
+
interface MemoryHistoryPage {
|
|
1295
|
+
/** Most versions to return, at most 200. Omit for the full history. */
|
|
1296
|
+
maxCount?: number;
|
|
1297
|
+
/** Return only versions with a lower id: the last id of the previous page. */
|
|
1298
|
+
beforeId?: number;
|
|
1299
|
+
}
|
|
987
1300
|
/**
|
|
988
1301
|
* Full version history — active + inactive, most recent first. Used
|
|
989
|
-
* by rollback UX to choose a target version.
|
|
1302
|
+
* by rollback UX to choose a target version. Pass `page` to read it in
|
|
1303
|
+
* pages; this needs a Dashboard and chain that support paging.
|
|
990
1304
|
*/
|
|
991
|
-
declare function getMemoryHistory(auth: AgentAuth, chainOpts?: ChainOpts, filePath?: string | null): Promise<AgentMemoryEntry[]>;
|
|
1305
|
+
declare function getMemoryHistory(auth: AgentAuth, chainOpts?: ChainOpts, filePath?: string | null, page?: MemoryHistoryPage): Promise<AgentMemoryEntry[]>;
|
|
992
1306
|
/**
|
|
993
1307
|
* Fetch a single memory entry by version id, including its current
|
|
994
1308
|
* `is_active` state. Version ids are agent-unique on chain (not
|
|
@@ -1056,6 +1370,13 @@ interface ClassifyMemoryWriteOptions {
|
|
|
1056
1370
|
*
|
|
1057
1371
|
* Empty-content writes return `null`: they can't carry a poisoning
|
|
1058
1372
|
* payload, and the regular audit path still sees them.
|
|
1373
|
+
*
|
|
1374
|
+
* THROWS on host input it cannot read without side effects: a proxy, an accessor where a data
|
|
1375
|
+
* property is expected, a value with no safe projection, or one past the size bounds. Refusing is
|
|
1376
|
+
* deliberate - a silent `null` would report "not a memory write" for a call nobody could classify,
|
|
1377
|
+
* and memory protection would be skipped exactly where the input was strange. Callers that sit in a
|
|
1378
|
+
* host hook MUST catch it and turn it into a decision; `guardMemoryWrite` and
|
|
1379
|
+
* `MemoryGuardManager.handleBeforeToolCall` already do.
|
|
1059
1380
|
*/
|
|
1060
1381
|
declare function classifyMemoryWrite(event: unknown, ctx: unknown, opts?: ClassifyMemoryWriteOptions): MemoryEntry | null;
|
|
1061
1382
|
|
|
@@ -1081,6 +1402,8 @@ interface GuardMemoryWriteInput extends ClassifyMemoryWriteOptions {
|
|
|
1081
1402
|
verifyPubKey?: string;
|
|
1082
1403
|
/** Org name for chain resolution (public vs org-private chain). */
|
|
1083
1404
|
orgName?: string;
|
|
1405
|
+
/** Explicit chain target when the host already resolved and verified it. */
|
|
1406
|
+
chainOpts?: ChainOpts;
|
|
1084
1407
|
/** LLM confidence threshold for yellow escalation. Default 0.6. */
|
|
1085
1408
|
threshold?: number;
|
|
1086
1409
|
/** When false, red verdicts log but don't block. Default true. */
|
|
@@ -1089,6 +1412,17 @@ interface GuardMemoryWriteInput extends ClassifyMemoryWriteOptions {
|
|
|
1089
1412
|
debug?: boolean;
|
|
1090
1413
|
/** Optional logger for debug probe + persist-failure warnings. */
|
|
1091
1414
|
logger?: GuardLogger;
|
|
1415
|
+
/** Agent home directory names to accept beyond the built-in list. */
|
|
1416
|
+
agentHomeDirs?: string[];
|
|
1417
|
+
/**
|
|
1418
|
+
* Root the caller keeps memory under, when it is not an agent home.
|
|
1419
|
+
*
|
|
1420
|
+
* Only pass a value the host stated outright. A root defaulted from the
|
|
1421
|
+
* process working directory would make whichever directory the host happened
|
|
1422
|
+
* to start in look like a memory store — which is how a stray MEMORY.md once
|
|
1423
|
+
* ended up inside a plugin checkout.
|
|
1424
|
+
*/
|
|
1425
|
+
memoryRoot?: string;
|
|
1092
1426
|
}
|
|
1093
1427
|
/** Plugin-facing decision. Shape mirrors what plugins return from `before_tool_call`. */
|
|
1094
1428
|
interface GuardMemoryDecision {
|
|
@@ -1103,25 +1437,57 @@ interface GuardMemoryWriteResult {
|
|
|
1103
1437
|
decision?: GuardMemoryDecision;
|
|
1104
1438
|
/** Present when handled and scan ran. Absent when scan threw. */
|
|
1105
1439
|
scanResult?: MemoryScanResult;
|
|
1106
|
-
/** Present when handled. True
|
|
1440
|
+
/** Present when handled. True only after the chain transaction confirms. */
|
|
1107
1441
|
committed?: boolean;
|
|
1108
1442
|
}
|
|
1109
1443
|
/**
|
|
1110
|
-
*
|
|
1111
|
-
*
|
|
1112
|
-
*
|
|
1444
|
+
* Guard a memory write, and record what was decided.
|
|
1445
|
+
*
|
|
1446
|
+
* Wraps the decision rather than threading telemetry through its eight exits,
|
|
1447
|
+
* so a later return added inside cannot quietly stop being counted.
|
|
1113
1448
|
*
|
|
1114
|
-
*
|
|
1115
|
-
*
|
|
1116
|
-
*
|
|
1117
|
-
* - `green` → persisted with LLM score; decision allows
|
|
1449
|
+
* Only a call this guard actually handled is recorded. A tool call that was
|
|
1450
|
+
* never a memory write is not a memory operation, and counting it would put
|
|
1451
|
+
* every unrelated edit into the number a memory migration reads.
|
|
1118
1452
|
*
|
|
1119
|
-
*
|
|
1120
|
-
*
|
|
1121
|
-
* existing plugin behaviour — chain is for audit/recovery, not gating.
|
|
1453
|
+
* @param input - The tool call and the agent to judge it for.
|
|
1454
|
+
* @returns What the guard decided; unchanged by the recording.
|
|
1122
1455
|
*/
|
|
1123
1456
|
declare function guardMemoryWrite(input: GuardMemoryWriteInput): Promise<GuardMemoryWriteResult>;
|
|
1124
1457
|
|
|
1458
|
+
/**
|
|
1459
|
+
* The chain slot of a memory file, computed the same way everywhere.
|
|
1460
|
+
*
|
|
1461
|
+
* The Rust core finds the slot by stripping the agent's home from the file's
|
|
1462
|
+
* path, as an exact string prefix. The file path arrives resolved
|
|
1463
|
+
* (`path.resolve`), but the home did not: on Windows `HOME=/home/agent`
|
|
1464
|
+
* resolves the file to `C:\home\agent\...` and never matches, and a host that
|
|
1465
|
+
* spells the drive or the user folder differently (`c:\users\me` against
|
|
1466
|
+
* `C:\Users\Me`, both the same folder) did not match either. A file with no
|
|
1467
|
+
* slot is scanned but never recorded on chain, silently, so the on-chain
|
|
1468
|
+
* version record and its rollback/read checks were skipped for it.
|
|
1469
|
+
*
|
|
1470
|
+
* Here the home (and the memory root) is resolved like the file, and on a
|
|
1471
|
+
* case-insensitive file system it is passed to the core spelled the way the
|
|
1472
|
+
* file path spells it. The slot itself, the part below the agent home, keeps
|
|
1473
|
+
* the file's own spelling, so slots recorded before this change still match.
|
|
1474
|
+
*
|
|
1475
|
+
* Known limit: a folder with NTFS per-directory case sensitivity enabled
|
|
1476
|
+
* (`fsutil file setCaseSensitiveInfo`, or one created from WSL) can hold both
|
|
1477
|
+
* `Me` and `me`; there ASCII case does separate folders, and a sibling spelled
|
|
1478
|
+
* in another case would share the home's slots. Creating one needs write
|
|
1479
|
+
* access to the home's parent. A follow-up can confirm the same folder on disk
|
|
1480
|
+
* when the spellings differ.
|
|
1481
|
+
*/
|
|
1482
|
+
|
|
1483
|
+
/** Path semantics: `node:path` here, `path.win32` / `path.posix` in tests. */
|
|
1484
|
+
type PathImpl = typeof nodePath;
|
|
1485
|
+
/**
|
|
1486
|
+
* The chain slot for `target`, or null when it gets no chain record. `p`
|
|
1487
|
+
* selects path semantics (tests pass `path.win32` to check Windows anywhere).
|
|
1488
|
+
*/
|
|
1489
|
+
declare function memorySlotOf(target: string, home: string, root?: string, extraHomes?: string[], p?: PathImpl): string | null;
|
|
1490
|
+
|
|
1125
1491
|
/**
|
|
1126
1492
|
* Aligns a local `MemoryPointer` with chain's active memory version
|
|
1127
1493
|
* via a TTL-cached pointer check. Inside the TTL window: no-op.
|
|
@@ -1148,6 +1514,8 @@ interface SyncMemoryOptions {
|
|
|
1148
1514
|
/** Skip the TTL gate and force a chain check this call. Default false. */
|
|
1149
1515
|
force?: boolean;
|
|
1150
1516
|
chainOpts?: ChainOpts;
|
|
1517
|
+
/** Exact chain slot for the managed file; omission keeps the cross-file API behavior. */
|
|
1518
|
+
filePath?: string;
|
|
1151
1519
|
}
|
|
1152
1520
|
/**
|
|
1153
1521
|
* `drifted: false` — pointer is still valid; caller can keep serving the local copy.
|
|
@@ -1181,10 +1549,19 @@ declare class PointerStore {
|
|
|
1181
1549
|
private cache;
|
|
1182
1550
|
private loading;
|
|
1183
1551
|
constructor(filePath: string);
|
|
1184
|
-
/**
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1552
|
+
/**
|
|
1553
|
+
* The pointer for one agent's file, or a zero-pointer forcing a sync.
|
|
1554
|
+
*
|
|
1555
|
+
* @param filePath - The file's chain slot, i.e. its basename.
|
|
1556
|
+
*/
|
|
1557
|
+
get(agentPubkeyHex: string, filePath: string): Promise<MemoryPointer>;
|
|
1558
|
+
/**
|
|
1559
|
+
* Persist one file's pointer, leaving the agent's other files alone.
|
|
1560
|
+
*
|
|
1561
|
+
* Write failures are reported to `onError` rather than thrown: a cache that
|
|
1562
|
+
* cannot be written must not take down the read it was speeding up.
|
|
1563
|
+
*/
|
|
1564
|
+
set(agentPubkeyHex: string, filePath: string, pointer: MemoryPointer, onError?: (err: Error) => void): Promise<void>;
|
|
1188
1565
|
private ensureLoaded;
|
|
1189
1566
|
private loadOnce;
|
|
1190
1567
|
private persist;
|
|
@@ -1196,6 +1573,8 @@ declare function defaultPointerPath(workspaceDir?: string): string;
|
|
|
1196
1573
|
interface WrappedLogger {
|
|
1197
1574
|
info(message: string, meta?: Record<string, unknown>): void;
|
|
1198
1575
|
warn(message: string, meta?: Record<string, unknown>): void;
|
|
1576
|
+
/** Wait for queued writes and surface any lost log entry. */
|
|
1577
|
+
flush(): Promise<void>;
|
|
1199
1578
|
}
|
|
1200
1579
|
interface UpstreamLogger {
|
|
1201
1580
|
info: (...args: unknown[]) => void;
|
|
@@ -1224,6 +1603,13 @@ interface ClassifyMemoryReadOptions {
|
|
|
1224
1603
|
* Caller-supplied `patterns` are MERGED with the defaults (matches
|
|
1225
1604
|
* Node's original behavior — extending in one plugin doesn't disable
|
|
1226
1605
|
* standard coverage).
|
|
1606
|
+
*
|
|
1607
|
+
* THROWS on host input it cannot read without side effects: a proxy, an accessor where a data
|
|
1608
|
+
* property is expected, a value with no safe projection, or one past the size bounds. Refusing is
|
|
1609
|
+
* deliberate - a silent `null` would report "not a memory write" for a call nobody could classify,
|
|
1610
|
+
* and memory protection would be skipped exactly where the input was strange. Callers that sit in a
|
|
1611
|
+
* host hook MUST catch it and turn it into a decision; `guardMemoryWrite` and
|
|
1612
|
+
* `MemoryGuardManager.handleBeforeToolCall` already do.
|
|
1227
1613
|
*/
|
|
1228
1614
|
declare function classifyMemoryRead(event: unknown, ctx: unknown, opts?: ClassifyMemoryReadOptions): boolean;
|
|
1229
1615
|
|
|
@@ -1248,10 +1634,10 @@ interface HookDecision {
|
|
|
1248
1634
|
* failure, a rolled-back version), and a host must never re-judge its way past
|
|
1249
1635
|
* one.
|
|
1250
1636
|
*
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1637
|
+
* Absent or false means the guard reached no decision — for example, the scan
|
|
1638
|
+
* never ran or this manager does not own the requested file. In enforce mode,
|
|
1639
|
+
* failed chain verification of the managed file is a block, never an unaudited
|
|
1640
|
+
* allow. In observe mode unverified calls remain unaudited.
|
|
1255
1641
|
*
|
|
1256
1642
|
* So the host rule is:
|
|
1257
1643
|
* `if (d.block) deny; else if (d.audited) allow; else judge it yourself;`
|
|
@@ -1270,6 +1656,17 @@ interface MemoryGuardManagerOptions {
|
|
|
1270
1656
|
workspaceDir: string;
|
|
1271
1657
|
/** Absolute MEMORY.md path. Default `<workspaceDir>/MEMORY.md`. */
|
|
1272
1658
|
memoryFilePath?: string;
|
|
1659
|
+
/**
|
|
1660
|
+
* Root this host keeps memory under, when it is not an agent home.
|
|
1661
|
+
*
|
|
1662
|
+
* Only set this from a value the host stated outright — never from
|
|
1663
|
+
* `process.cwd()`. A guessed root makes whichever directory the host started
|
|
1664
|
+
* in look like a memory store, which is how a stray MEMORY.md once ended up
|
|
1665
|
+
* inside a plugin checkout.
|
|
1666
|
+
*/
|
|
1667
|
+
memoryRoot?: string;
|
|
1668
|
+
/** Agent home directory names to accept beyond the built-in list. */
|
|
1669
|
+
agentHomeDirs?: string[];
|
|
1273
1670
|
/** Persistent pointer file. Default `<workspaceDir>/.atbash/memory-pointer.json`. */
|
|
1274
1671
|
pointerFilePath?: string;
|
|
1275
1672
|
/** File-backed log. Default `<workspaceDir>/.atbash/plugin.log`. */
|
|
@@ -1316,11 +1713,45 @@ declare class MemoryGuardManager {
|
|
|
1316
1713
|
private readonly pointerStore;
|
|
1317
1714
|
private readonly logger;
|
|
1318
1715
|
private readonly memoryFilePath;
|
|
1716
|
+
/** Base for resolving the relative paths a host sends. */
|
|
1717
|
+
private readonly workspaceDir;
|
|
1718
|
+
/** Set by `verifyOneFile` when the file it checked was actually on chain. */
|
|
1719
|
+
private lastVerified;
|
|
1319
1720
|
private readonly ttlMs;
|
|
1320
1721
|
private readonly rollbackMinScore;
|
|
1321
1722
|
private readonly enforce;
|
|
1322
1723
|
private readonly agentPubkeyHex;
|
|
1724
|
+
/**
|
|
1725
|
+
* Memoized org→chain resolution. Reads have to hit the SAME chain
|
|
1726
|
+
* writes did, so an org-scoped guard must resolve `orgName` to
|
|
1727
|
+
* network exactly like `commitMemoryVersion` does. Without this
|
|
1728
|
+
* cache the read path would either (a) hit the SDK-default chain
|
|
1729
|
+
* every time — silently returning "no active memory on chain" when
|
|
1730
|
+
* writes landed on the org's actual chain, or (b) hammer
|
|
1731
|
+
* `/api/org-network` on every read. `undefined` means "not yet
|
|
1732
|
+
* resolved"; a resolved `null` means "no org / use raw chainOpts".
|
|
1733
|
+
*/
|
|
1734
|
+
private _resolvedChainOpts;
|
|
1735
|
+
private _resolveChainInflight?;
|
|
1323
1736
|
constructor(opts: MemoryGuardManagerOptions);
|
|
1737
|
+
/**
|
|
1738
|
+
* Carry this manager's host into `chainOpts`.
|
|
1739
|
+
*
|
|
1740
|
+
* Memory reads reach the chain through that host, and they are handed only
|
|
1741
|
+
* `chainOpts` — without this a self-hosted deployment would read from the
|
|
1742
|
+
* compiled-in default host while writing to its own.
|
|
1743
|
+
*/
|
|
1744
|
+
private withEndpoint;
|
|
1745
|
+
/**
|
|
1746
|
+
* Resolve `orgName` → chain once, cache forever. `commitMemoryVersion`
|
|
1747
|
+
* already does this for writes; without the same call on the read
|
|
1748
|
+
* path, a client on the SDK's baked default chain reads from the wrong
|
|
1749
|
+
* chain and reports "no active memory" for an agent whose writes did
|
|
1750
|
+
* land — on the org's actual chain. An explicit `chainOpts.blockchainRid`
|
|
1751
|
+
* still wins (caller vouched for it); everything else honors the
|
|
1752
|
+
* dashboard's `org_networks` map.
|
|
1753
|
+
*/
|
|
1754
|
+
private resolveChainOpts;
|
|
1324
1755
|
/**
|
|
1325
1756
|
* One-shot chain probe at plugin registration. Refreshes MEMORY.md
|
|
1326
1757
|
* from chain when drifted and score passes threshold. Fire-and-forget
|
|
@@ -1328,15 +1759,27 @@ declare class MemoryGuardManager {
|
|
|
1328
1759
|
*/
|
|
1329
1760
|
runBootProbe(): Promise<void>;
|
|
1330
1761
|
/**
|
|
1331
|
-
*
|
|
1332
|
-
* Returns `null` when it did not — either the event isn't memory-related, or it
|
|
1333
|
-
* is but the guard could not check it. In both cases the host falls through to
|
|
1334
|
-
* its own audit.
|
|
1762
|
+
* Bring one chain file into step with its local counterpart.
|
|
1335
1763
|
*
|
|
1336
|
-
*
|
|
1337
|
-
*
|
|
1338
|
-
*
|
|
1764
|
+
* Only a file that already exists locally is touched. Restoring one that is
|
|
1765
|
+
* absent would mean choosing where to create it, and the root is a guess the
|
|
1766
|
+
* moment more than one could apply — the same guess that once wrote a
|
|
1767
|
+
* MEMORY.md into a plugin checkout.
|
|
1768
|
+
*
|
|
1769
|
+
* @returns What happened, for the single summary line the caller logs.
|
|
1770
|
+
*/
|
|
1771
|
+
private syncOneAtBoot;
|
|
1772
|
+
/**
|
|
1773
|
+
* Where a chain slot's file lives locally, or null when we do not have it.
|
|
1774
|
+
*
|
|
1775
|
+
* A stated root is tried first, then each agent home that actually exists in
|
|
1776
|
+
* the user's home directory — the same rule that produced the slot, run
|
|
1777
|
+
* backwards. Only an existing file is returned: creating one would mean
|
|
1778
|
+
* picking a root, and picking is guessing.
|
|
1339
1779
|
*/
|
|
1780
|
+
private locate;
|
|
1781
|
+
/** Roots a chain slot may be joined to, most specific first. */
|
|
1782
|
+
private memoryRoots;
|
|
1340
1783
|
handleBeforeToolCall(event: unknown, ctx: unknown): Promise<HookDecision | null>;
|
|
1341
1784
|
private mapGuardResult;
|
|
1342
1785
|
/**
|
|
@@ -1354,9 +1797,70 @@ declare class MemoryGuardManager {
|
|
|
1354
1797
|
* also covers events carrying two different path keys, where the classifier
|
|
1355
1798
|
* and the host could otherwise disagree about which one is authoritative.
|
|
1356
1799
|
*/
|
|
1357
|
-
|
|
1800
|
+
/**
|
|
1801
|
+
* The memory files this tool call reads, as absolute paths.
|
|
1802
|
+
*
|
|
1803
|
+
* Relative paths resolve against the workspace, not `process.cwd()`. The host
|
|
1804
|
+
* sends paths relative to the agent's workspace; resolving them against the
|
|
1805
|
+
* process's own directory made the guard protect whichever directory the host
|
|
1806
|
+
* happened to start in, which on one machine was a plugin checkout.
|
|
1807
|
+
*
|
|
1808
|
+
* @returns Every named target, de-duplicated; empty when the call names none.
|
|
1809
|
+
*/
|
|
1810
|
+
private readTargets;
|
|
1811
|
+
/**
|
|
1812
|
+
* Say what the read classifier saw and what it concluded.
|
|
1813
|
+
*
|
|
1814
|
+
* The write path has `emitDebugProbe`; this is its counterpart, so a tool
|
|
1815
|
+
* call can be followed across the fork instead of only after it. `false` here
|
|
1816
|
+
* is the normal answer for a write — it means the call goes to the write
|
|
1817
|
+
* classifier next, not that it was ignored.
|
|
1818
|
+
*
|
|
1819
|
+
* @param isMemoryRead - What `classifyMemoryRead` returned.
|
|
1820
|
+
*/
|
|
1821
|
+
private emitReadProbe;
|
|
1822
|
+
/**
|
|
1823
|
+
* The chain slot for a path, or null when the file gets no chain record.
|
|
1824
|
+
*
|
|
1825
|
+
* One helper so the boot probe and every read agree: taking a basename in one
|
|
1826
|
+
* place and a relative path in the other would verify a file against a record
|
|
1827
|
+
* that is not its own.
|
|
1828
|
+
*/
|
|
1829
|
+
private slotFor;
|
|
1830
|
+
/**
|
|
1831
|
+
* Verify every memory file this call reads, each against its own chain slot.
|
|
1832
|
+
*
|
|
1833
|
+
* A call naming several files is only cleared when all of them are, so one
|
|
1834
|
+
* unverifiable file cannot ride along with a verified one.
|
|
1835
|
+
*
|
|
1836
|
+
* @returns A block for the first file that fails, an audited allow when all
|
|
1837
|
+
* were verified, or null when none of them is on chain.
|
|
1838
|
+
*/
|
|
1358
1839
|
private handleMemoryRead;
|
|
1840
|
+
/**
|
|
1841
|
+
* Check one memory file against the chain slot of the same name.
|
|
1842
|
+
*
|
|
1843
|
+
* A file with no chain version is passed through rather than blocked: there
|
|
1844
|
+
* is no claim to protect, so refusing would only stop an agent reading memory
|
|
1845
|
+
* it has never committed. A file that IS on chain must match, or the read is
|
|
1846
|
+
* refused — that is the whole guarantee.
|
|
1847
|
+
*
|
|
1848
|
+
* @returns A decision when the read must not proceed, else null.
|
|
1849
|
+
*/
|
|
1850
|
+
private verifyOneFile;
|
|
1851
|
+
/** Complete queued audit-log writes before a host shuts down or removes its workspace. */
|
|
1852
|
+
flushLogs(): Promise<void>;
|
|
1853
|
+
/**
|
|
1854
|
+
* A read this guard could not verify.
|
|
1855
|
+
*
|
|
1856
|
+
* Enforcing, that is a block. Observing, the host audits it as usual — but
|
|
1857
|
+
* the reason is said out loud either way, or an unverified read looks
|
|
1858
|
+
* identical to a clean one in the log.
|
|
1859
|
+
*/
|
|
1860
|
+
private unverifiedRead;
|
|
1359
1861
|
private writeMemoryAtomic;
|
|
1862
|
+
/** Replace `target` in one step, so a reader never sees a half-written file. */
|
|
1863
|
+
private writeFileAtomic;
|
|
1360
1864
|
}
|
|
1361
1865
|
declare function createMemoryGuardManager(opts: MemoryGuardManagerOptions): MemoryGuardManager;
|
|
1362
1866
|
|
|
@@ -1390,6 +1894,20 @@ interface TelemetryConfig {
|
|
|
1390
1894
|
* `{ Authorization: "Bearer <hex>" }`). Required to actually export.
|
|
1391
1895
|
*/
|
|
1392
1896
|
getAuthHeaders?: () => Record<string, string>;
|
|
1897
|
+
/**
|
|
1898
|
+
* Hashes the agent key before it is emitted on a wide event.
|
|
1899
|
+
*
|
|
1900
|
+
* Defaults to an unsalted SHA-256, which is de-identification rather than
|
|
1901
|
+
* anonymisation: agent pubkeys are public on chain and can be enumerated, so
|
|
1902
|
+
* the mapping is recoverable by anyone holding that list. Supply a salted
|
|
1903
|
+
* hasher to make it uncorrelatable, at the cost of joining across
|
|
1904
|
+
* deployments.
|
|
1905
|
+
*
|
|
1906
|
+
* Injected rather than imported so the telemetry modules need nothing from
|
|
1907
|
+
* the native addon. Left unset, the agent field is dropped from events
|
|
1908
|
+
* rather than falling back to the raw key.
|
|
1909
|
+
*/
|
|
1910
|
+
hashAgentKey?: (pubkeyHex: string) => string;
|
|
1393
1911
|
}
|
|
1394
1912
|
declare function setupTelemetry(config: TelemetryConfig): void;
|
|
1395
1913
|
/**
|
|
@@ -1412,6 +1930,111 @@ declare function flushTelemetry(): Promise<void>;
|
|
|
1412
1930
|
*/
|
|
1413
1931
|
declare function shutdownTelemetry(): Promise<void>;
|
|
1414
1932
|
|
|
1933
|
+
/**
|
|
1934
|
+
* Wide events: one row per SDK operation, alongside the counters.
|
|
1935
|
+
*
|
|
1936
|
+
* The counters in `telemetry.ts` are aggregated inside this process before
|
|
1937
|
+
* export, so Honeycomb never receives a per-operation row. That is fine for
|
|
1938
|
+
* "is it up" and useless for everything else: a question nobody attached an
|
|
1939
|
+
* attribute for in advance cannot be answered later, because the data to
|
|
1940
|
+
* answer it never existed. "Which org sees the most failures", "what preceded
|
|
1941
|
+
* a fail-closed", "is the new release slower" are all that shape.
|
|
1942
|
+
*
|
|
1943
|
+
* So each operation also emits one event carrying its whole context. The
|
|
1944
|
+
* counters stay — they are the right tool for health boards and alerts, and
|
|
1945
|
+
* they are not sampled.
|
|
1946
|
+
*
|
|
1947
|
+
* TWO RULES SHAPE THIS MODULE.
|
|
1948
|
+
*
|
|
1949
|
+
* The payload is METADATA ONLY, and the allowlist below is the whole of it:
|
|
1950
|
+
* function name, outcome, latency, error class, error status and path, SDK
|
|
1951
|
+
* version, chain, and a hash of the agent key. Action text, tool arguments, policy text, organisation
|
|
1952
|
+
* names and keys never appear — not as a field that is emptied, but as a field
|
|
1953
|
+
* that does not exist, so there is nothing to forget to strip.
|
|
1954
|
+
*
|
|
1955
|
+
* The agent key is hashed, never sent raw, and the hasher is INJECTED rather
|
|
1956
|
+
* than imported: this module needs nothing from the native addon. With no
|
|
1957
|
+
* hasher supplied the field is DROPPED rather than falling back to the raw
|
|
1958
|
+
* key, so the guarantee does not depend on wiring somebody could forget.
|
|
1959
|
+
*
|
|
1960
|
+
* NOTE on what hashing does and does not buy. Agent pubkeys are public on
|
|
1961
|
+
* chain and can be enumerated, so an UNSALTED hash is reversible by anyone who
|
|
1962
|
+
* can read the chain: it is de-identification, not anonymisation. A salted
|
|
1963
|
+
* hasher makes it uncorrelatable and costs cross-deployment joins. Which one
|
|
1964
|
+
* is wanted is the caller's decision; this module only guarantees the raw key
|
|
1965
|
+
* never leaves.
|
|
1966
|
+
*
|
|
1967
|
+
* And the richer payload has its own switch. Counters carry a function name
|
|
1968
|
+
* and a source. These events carry agent and org identity off a customer's
|
|
1969
|
+
* machine, which is a different proposition for a security product, so
|
|
1970
|
+
* `ATBASH_TELEMETRY_EVENTS_DISABLED=1` turns them off while leaving the health
|
|
1971
|
+
* counters on. Both remain subject to the existing global opt-out.
|
|
1972
|
+
*/
|
|
1973
|
+
|
|
1974
|
+
/** Attributes an event may carry. Anything not listed here cannot be emitted. */
|
|
1975
|
+
interface OperationEvent {
|
|
1976
|
+
/** SDK function, matching the counter's `function.name` so the two join. */
|
|
1977
|
+
functionName: string;
|
|
1978
|
+
durationMs: number;
|
|
1979
|
+
status: "success" | "error";
|
|
1980
|
+
/**
|
|
1981
|
+
* Hex pubkey of the agent the call was made as. Hashed before it is emitted,
|
|
1982
|
+
* and omitted entirely when no hasher is configured.
|
|
1983
|
+
*/
|
|
1984
|
+
agentPubkey?: string;
|
|
1985
|
+
/**
|
|
1986
|
+
* Blockchain RID of the chain this call concerned.
|
|
1987
|
+
*
|
|
1988
|
+
* The RID rather than a network label: it is public infrastructure, it is
|
|
1989
|
+
* unambiguous, and it identifies the deployment without naming a customer.
|
|
1990
|
+
*/
|
|
1991
|
+
chain?: string;
|
|
1992
|
+
/** Constructor name of the thrown error, e.g. `AtbashAPIError`. */
|
|
1993
|
+
errorClass?: string;
|
|
1994
|
+
/** HTTP status, or 0 when the request never completed. */
|
|
1995
|
+
errorStatus?: number;
|
|
1996
|
+
/**
|
|
1997
|
+
* Request path the status came from, e.g. `/api/v1/judge`.
|
|
1998
|
+
*
|
|
1999
|
+
* The class alone does not say what failed: several routes answer one call
|
|
2000
|
+
* and more than one can 404, so `AtbashAPIError` cannot distinguish "this
|
|
2001
|
+
* agent is not registered" from "the chain-routing lookup did not resolve".
|
|
2002
|
+
* The path settles it.
|
|
2003
|
+
*
|
|
2004
|
+
* Carries no query string — `requestPath` strips it at the point the error
|
|
2005
|
+
* is built, because a query string carries org names, tool call ids and the
|
|
2006
|
+
* agent pubkey. Structured and already sanitised, so this stays inside the
|
|
2007
|
+
* metadata rule where an error message would not.
|
|
2008
|
+
*/
|
|
2009
|
+
errorPath?: string;
|
|
2010
|
+
/**
|
|
2011
|
+
* Short categorical result, when "success" is too coarse — e.g. a memory
|
|
2012
|
+
* write that scanned clean but never reached the chain.
|
|
2013
|
+
*
|
|
2014
|
+
* Categorical by contract: a value a caller chooses from a fixed vocabulary,
|
|
2015
|
+
* never free text and never anything derived from user content.
|
|
2016
|
+
*/
|
|
2017
|
+
outcome?: string;
|
|
2018
|
+
}
|
|
2019
|
+
/** Hashes an agent key for emission. Supplied by `setupTelemetry`. */
|
|
2020
|
+
type AgentKeyHasher = (pubkeyHex: string) => string;
|
|
2021
|
+
declare function configureEvents(next: Logger | null, opts?: {
|
|
2022
|
+
version?: string;
|
|
2023
|
+
source?: string;
|
|
2024
|
+
hashAgentKey?: AgentKeyHasher;
|
|
2025
|
+
}): void;
|
|
2026
|
+
/** True when an event would actually be emitted. Exported for tests and callers that build context lazily. */
|
|
2027
|
+
declare function eventsAreOn(): boolean;
|
|
2028
|
+
/**
|
|
2029
|
+
* Emit one wide event for a completed operation.
|
|
2030
|
+
*
|
|
2031
|
+
* Never throws and never blocks: telemetry failing must not change what the
|
|
2032
|
+
* caller observes. Does nothing when events are off.
|
|
2033
|
+
*
|
|
2034
|
+
* @param e - The completed operation.
|
|
2035
|
+
*/
|
|
2036
|
+
declare function recordEvent(e: OperationEvent): void;
|
|
2037
|
+
|
|
1415
2038
|
/**
|
|
1416
2039
|
* Rust core does the work; `browser/encrypted-toolcall.ts` mirrors it for the
|
|
1417
2040
|
* browser and must produce the same columns.
|
|
@@ -1509,4 +2132,4 @@ declare function containsSecret(text: string): boolean;
|
|
|
1509
2132
|
declare function createMemorySnapshot(entries: MemoryEntry[], takenAt: number): MemorySnapshot;
|
|
1510
2133
|
declare function diffMemorySnapshots(before: MemorySnapshot, after: MemorySnapshot): MemoryDiffResult;
|
|
1511
2134
|
|
|
1512
|
-
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,
|
|
2135
|
+
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_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, JudgeRefusalError, type JudgeResult, type JudgmentState, type JudgmentStatus, KEY_FILENAMES, type KeyPair, type LogToolCallOptions, type LogToolCallResult, type MemoryAnomaly, type MemoryDiffResult, type MemoryEntry, MemoryGuardManager, type MemoryGuardManagerOptions, type MemoryHistoryPage, MemoryIntegrityError, type MemoryPointer, type MemoryRollbackEvent, type MemoryScanOptions, type MemoryScanResult, type MemoryScanVerdict, type MemorySnapshot, type ModifiedEntry, type Network, type OperationEvent, type OrgSubscription, PRIVATE_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 VerdictRecord, type WrappedLogger, bootSyncFailureLine, buildAllowedJudgeHosts, canonicalAllow, chainForNetwork, chooseKeyPath, claimHashHex, classifyMemoryRead, classifyMemoryWrite, columnAad, commitMemoryVersion, configureEvents, configureJailHold, containsEvasionCharacters, containsSecret, createFileLogger, createMemoryGuardManager, createMemorySnapshot, decryptForOrg, decryptMemoryContent, defaultPluginLogPath, defaultPointerPath, deriveMemoryKey, derivePublicKey, diffMemorySnapshots, encryptForOrg, encryptMemoryContent, encryptedLength, eventsAreOn, flushTelemetry, generateKeypair, getActiveAgentMemory, getActiveMemoryId, getConfigDir, getConfigPath, getMemoryById, getMemoryHistory, getRecentAgentMemory, getRollbackHistory, guardMemoryWrite, isEnvelope, isJailHeld, isValidPrivateKey, judgeVerifyKeys, keyFingerprintOf, keyPathCandidates, loadAgent, loadAgentFromFile, loadUserConfig, memorySlotOf, normalizeActionForHash, normalizeActionType, normalizeForMatching, normalizeStatus, normalizeVerdict, packEnvelope, parseEnvelope, pubkeyToHex, recordCall, recordDuration, recordEvent, redactJsonStrings, redactSecrets, releaseJailHolds, resolve, resolveKeyPath, rollbackMemory, saveUserConfig, scanMemory, scanMemoryBatch, setLoopbackJudgePinsForTests, setupTelemetry, shutdownTelemetry, signEncryptedToolCall, signJudgeAction, signLogToolCall, syncLocalMemory, validateJudgeEndpoint, verifyJudgeResponseSignature, verifySignature };
|