@atbash/sdk 0.16.5-dev.0 → 0.17.0-dev.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -198,6 +198,11 @@ interface JudgeResult {
198
198
  * missing" — never infer the former from a null verdict alone.
199
199
  */
200
200
  status: string;
201
+ /**
202
+ * The judge's explicit refusal in the raw body (`explicitRefusal`): "BLOCK",
203
+ * "HOLD", or "" when it neither refused nor is a known refusal shape.
204
+ */
205
+ refusal?: "" | "BLOCK" | "HOLD";
201
206
  }
202
207
  interface JudgmentStatus {
203
208
  status: JudgmentState;
@@ -305,6 +310,13 @@ interface AtbashLogger {
305
310
  /** Options accepted by the `Atbash` constructor. */
306
311
  interface AtbashOptions {
307
312
  endpoint?: string;
313
+ /**
314
+ * Overall deadline for one `auditToolCall` decision, across every request
315
+ * it makes (org lookup, exists check, judge). Default 60 000 ms. When it
316
+ * passes the decision is an ERROR (denied unless `failClosed` is false).
317
+ * `timeoutMs` still bounds each single request.
318
+ */
319
+ decisionTimeoutMs?: number;
308
320
  timeoutMs?: number;
309
321
  /**
310
322
  * Full chain override — BRID + nodeUrls in one object. Wins over every
@@ -350,6 +362,16 @@ interface AtbashOptions {
350
362
  orgEncryptionPubKey?: string;
351
363
  /** When true (default), `auditToolCall` denies on any error. */
352
364
  failClosed?: boolean;
365
+ /**
366
+ * When true (the default), an answer that carries no enforcement decision
367
+ * (the audit tier's `{status:"logged"}` with no verdict) is refused:
368
+ * `auditToolCall` returns `{allow:false, verdict:"ERROR"}` whatever
369
+ * `failClosed` says, and `judgeAction().allow` / `getJudgmentStatus().allow`
370
+ * are false. Set it to `false` only to run deliberately in log-only mode
371
+ * (security review 2026-09-30, H6: an unsigned marker switched enforcement
372
+ * off).
373
+ */
374
+ requireEnforcement?: boolean;
353
375
  /**
354
376
  * Verbose diagnostics. Off by default. When on, a failed judge call also
355
377
  * logs the response body, which is the difference between "judge API failed"
@@ -400,6 +422,10 @@ interface FromConfigOptions {
400
422
  /** Default org name — see {@link AtbashOptions.orgName}. */
401
423
  orgName?: string;
402
424
  failClosed?: boolean;
425
+ /** See {@link AtbashOptions.requireEnforcement}. Default true. */
426
+ requireEnforcement?: boolean;
427
+ /** See {@link AtbashOptions.decisionTimeoutMs}. Default 60 000 ms. */
428
+ decisionTimeoutMs?: number;
403
429
  /** See {@link AtbashOptions.debug}. */
404
430
  debug?: boolean;
405
431
  logger?: AtbashLogger;
@@ -456,6 +482,10 @@ declare class Atbash {
456
482
  readonly orgEncryptionPubKey?: string;
457
483
  /** When true (default), `auditToolCall` denies on any error. */
458
484
  readonly failClosed: boolean;
485
+ /** When true (default), an unenforced (audit-tier) answer is refused. */
486
+ readonly requireEnforcement: boolean;
487
+ /** Overall deadline for one auditToolCall decision, in ms. */
488
+ readonly decisionTimeoutMs: number;
459
489
  /** Org key learned from the last agent-exists check, for this agent only. */
460
490
  private _orgKeyFromChain;
461
491
  private readonly debug;
@@ -559,6 +589,23 @@ declare class Atbash {
559
589
  * explicitly false.
560
590
  */
561
591
  auditToolCall(input: ToolCallInput): Promise<Decision>;
592
+ /**
593
+ * The verify key for one call (R4, governor tier-2 review). A per-call key
594
+ * may only narrow what the client accepts: on a client pinned to a judge
595
+ * key it must be that same key, never a replacement; on an unpinned client
596
+ * it adds the check.
597
+ */
598
+ private effectiveVerifyKey;
599
+ /**
600
+ * Collapse a judge result into a {@link Decision}. The most restrictive
601
+ * signal wins (security review 2026-09-30, H1): `action_type`, `verdict`
602
+ * and the canonical `allow` are each able to deny, and only a result where
603
+ * all three agree may execute. A present `allow` / `decision.allow` that is
604
+ * not exactly `true` is the judge declining to grant permission, so it
605
+ * denies even under `failClosed: false` — that option relaxes *errors*, it
606
+ * never overrides a refusal.
607
+ */
608
+ private decide;
562
609
  /**
563
610
  * One exit for every judge failure.
564
611
  *
@@ -568,6 +615,12 @@ declare class Atbash {
568
615
  * The response body follows only under `debug`, since it can echo the action.
569
616
  */
570
617
  private failJudge;
618
+ /**
619
+ * The canonical permission for a response body under this client's
620
+ * settings: {@link canonicalAllow}, minus the audit tier when
621
+ * `requireEnforcement` is on. Never more permissive than `auditToolCall`.
622
+ */
623
+ private executable;
571
624
  private fail;
572
625
  /**
573
626
  * Return the current status of a previously submitted judgment.
@@ -1111,6 +1164,8 @@ interface GuardMemoryWriteInput extends ClassifyMemoryWriteOptions {
1111
1164
  verifyPubKey?: string;
1112
1165
  /** Org name for chain resolution (public vs org-private chain). */
1113
1166
  orgName?: string;
1167
+ /** Explicit chain target when the host already resolved and verified it. */
1168
+ chainOpts?: ChainOpts;
1114
1169
  /** LLM confidence threshold for yellow escalation. Default 0.6. */
1115
1170
  threshold?: number;
1116
1171
  /** When false, red verdicts log but don't block. Default true. */
@@ -1133,7 +1188,7 @@ interface GuardMemoryWriteResult {
1133
1188
  decision?: GuardMemoryDecision;
1134
1189
  /** Present when handled and scan ran. Absent when scan threw. */
1135
1190
  scanResult?: MemoryScanResult;
1136
- /** Present when handled. True when a chain-commit was dispatched (fire-and-forget). */
1191
+ /** Present when handled. True only after the chain transaction confirms. */
1137
1192
  committed?: boolean;
1138
1193
  }
1139
1194
  /**
@@ -1143,12 +1198,13 @@ interface GuardMemoryWriteResult {
1143
1198
  *
1144
1199
  * Verdict handling:
1145
1200
  * - `red` → not persisted to chain; decision blocks (unless `enforce: false`)
1146
- * - `yellow` → persisted with LLM score; decision allows
1147
- * - `green` → persisted with LLM score; decision allows
1201
+ * - `yellow` → persisted with its LLM score; decision allows once the chain confirms
1202
+ * - `green` → persisted with its LLM score; decision allows once the chain confirms
1203
+ * - anything else → not persisted; decision blocks (unless `enforce: false`)
1148
1204
  *
1149
- * Chain commit is fire-and-forget: network errors are logged via
1150
- * `logger.warn` but never surfaced to the caller. This mirrors the
1151
- * existing plugin behaviour — chain is for audit/recovery, not gating.
1205
+ * A write is acknowledged only after the chain transaction confirms, for
1206
+ * yellow exactly as for green. An unconfirmed write blocks in enforce mode
1207
+ * and remains unaudited in observe mode.
1152
1208
  */
1153
1209
  declare function guardMemoryWrite(input: GuardMemoryWriteInput): Promise<GuardMemoryWriteResult>;
1154
1210
 
@@ -1178,6 +1234,8 @@ interface SyncMemoryOptions {
1178
1234
  /** Skip the TTL gate and force a chain check this call. Default false. */
1179
1235
  force?: boolean;
1180
1236
  chainOpts?: ChainOpts;
1237
+ /** Exact chain slot for the managed file; omission keeps the cross-file API behavior. */
1238
+ filePath?: string;
1181
1239
  }
1182
1240
  /**
1183
1241
  * `drifted: false` — pointer is still valid; caller can keep serving the local copy.
@@ -1226,6 +1284,8 @@ declare function defaultPointerPath(workspaceDir?: string): string;
1226
1284
  interface WrappedLogger {
1227
1285
  info(message: string, meta?: Record<string, unknown>): void;
1228
1286
  warn(message: string, meta?: Record<string, unknown>): void;
1287
+ /** Wait for queued writes and surface any lost log entry. */
1288
+ flush(): Promise<void>;
1229
1289
  }
1230
1290
  interface UpstreamLogger {
1231
1291
  info: (...args: unknown[]) => void;
@@ -1285,10 +1345,10 @@ interface HookDecision {
1285
1345
  * failure, a rolled-back version), and a host must never re-judge its way past
1286
1346
  * one.
1287
1347
  *
1288
- * Absent or false means the guard reached no decision — it was inside its cache
1289
- * window, chain was unreachable, the scan never ran, the file it can vouch for
1290
- * is not the file being read, or it is in observe mode. Those calls are
1291
- * unaudited: fall through to your own judge exactly as for a `null` return.
1348
+ * Absent or false means the guard reached no decision — for example, the scan
1349
+ * never ran or this manager does not own the requested file. In enforce mode,
1350
+ * failed chain verification of the managed file is a block, never an unaudited
1351
+ * allow. In observe mode unverified calls remain unaudited.
1292
1352
  *
1293
1353
  * So the host rule is:
1294
1354
  * `if (d.block) deny; else if (d.audited) allow; else judge it yourself;`
@@ -1388,9 +1448,9 @@ declare class MemoryGuardManager {
1388
1448
  runBootProbe(): Promise<void>;
1389
1449
  /**
1390
1450
  * Returns a `HookDecision` when the guard reached a decision about this event.
1391
- * Returns `null` when it did not — either the event isn't memory-related, or it
1392
- * is but the guard could not check it. In both cases the host falls through to
1393
- * its own audit.
1451
+ * Returns `null` for non-memory events, other files this manager does not
1452
+ * own, or unverified observe-mode reads. An enforced read of the managed
1453
+ * file blocks when verification cannot complete.
1394
1454
  *
1395
1455
  * A returned decision carries `audited` (see `HookDecision`). Only
1396
1456
  * `{ allow: true, audited: true }` means "checked and cleared"; anything else
@@ -1415,6 +1475,9 @@ declare class MemoryGuardManager {
1415
1475
  */
1416
1476
  private vouchesForTarget;
1417
1477
  private handleMemoryRead;
1478
+ /** Complete queued audit-log writes before a host shuts down or removes its workspace. */
1479
+ flushLogs(): Promise<void>;
1480
+ private unverifiedRead;
1418
1481
  private writeMemoryAtomic;
1419
1482
  }
1420
1483
  declare function createMemoryGuardManager(opts: MemoryGuardManagerOptions): MemoryGuardManager;
package/dist/index.d.ts CHANGED
@@ -198,6 +198,11 @@ interface JudgeResult {
198
198
  * missing" — never infer the former from a null verdict alone.
199
199
  */
200
200
  status: string;
201
+ /**
202
+ * The judge's explicit refusal in the raw body (`explicitRefusal`): "BLOCK",
203
+ * "HOLD", or "" when it neither refused nor is a known refusal shape.
204
+ */
205
+ refusal?: "" | "BLOCK" | "HOLD";
201
206
  }
202
207
  interface JudgmentStatus {
203
208
  status: JudgmentState;
@@ -305,6 +310,13 @@ interface AtbashLogger {
305
310
  /** Options accepted by the `Atbash` constructor. */
306
311
  interface AtbashOptions {
307
312
  endpoint?: string;
313
+ /**
314
+ * Overall deadline for one `auditToolCall` decision, across every request
315
+ * it makes (org lookup, exists check, judge). Default 60 000 ms. When it
316
+ * passes the decision is an ERROR (denied unless `failClosed` is false).
317
+ * `timeoutMs` still bounds each single request.
318
+ */
319
+ decisionTimeoutMs?: number;
308
320
  timeoutMs?: number;
309
321
  /**
310
322
  * Full chain override — BRID + nodeUrls in one object. Wins over every
@@ -350,6 +362,16 @@ interface AtbashOptions {
350
362
  orgEncryptionPubKey?: string;
351
363
  /** When true (default), `auditToolCall` denies on any error. */
352
364
  failClosed?: boolean;
365
+ /**
366
+ * When true (the default), an answer that carries no enforcement decision
367
+ * (the audit tier's `{status:"logged"}` with no verdict) is refused:
368
+ * `auditToolCall` returns `{allow:false, verdict:"ERROR"}` whatever
369
+ * `failClosed` says, and `judgeAction().allow` / `getJudgmentStatus().allow`
370
+ * are false. Set it to `false` only to run deliberately in log-only mode
371
+ * (security review 2026-09-30, H6: an unsigned marker switched enforcement
372
+ * off).
373
+ */
374
+ requireEnforcement?: boolean;
353
375
  /**
354
376
  * Verbose diagnostics. Off by default. When on, a failed judge call also
355
377
  * logs the response body, which is the difference between "judge API failed"
@@ -400,6 +422,10 @@ interface FromConfigOptions {
400
422
  /** Default org name — see {@link AtbashOptions.orgName}. */
401
423
  orgName?: string;
402
424
  failClosed?: boolean;
425
+ /** See {@link AtbashOptions.requireEnforcement}. Default true. */
426
+ requireEnforcement?: boolean;
427
+ /** See {@link AtbashOptions.decisionTimeoutMs}. Default 60 000 ms. */
428
+ decisionTimeoutMs?: number;
403
429
  /** See {@link AtbashOptions.debug}. */
404
430
  debug?: boolean;
405
431
  logger?: AtbashLogger;
@@ -456,6 +482,10 @@ declare class Atbash {
456
482
  readonly orgEncryptionPubKey?: string;
457
483
  /** When true (default), `auditToolCall` denies on any error. */
458
484
  readonly failClosed: boolean;
485
+ /** When true (default), an unenforced (audit-tier) answer is refused. */
486
+ readonly requireEnforcement: boolean;
487
+ /** Overall deadline for one auditToolCall decision, in ms. */
488
+ readonly decisionTimeoutMs: number;
459
489
  /** Org key learned from the last agent-exists check, for this agent only. */
460
490
  private _orgKeyFromChain;
461
491
  private readonly debug;
@@ -559,6 +589,23 @@ declare class Atbash {
559
589
  * explicitly false.
560
590
  */
561
591
  auditToolCall(input: ToolCallInput): Promise<Decision>;
592
+ /**
593
+ * The verify key for one call (R4, governor tier-2 review). A per-call key
594
+ * may only narrow what the client accepts: on a client pinned to a judge
595
+ * key it must be that same key, never a replacement; on an unpinned client
596
+ * it adds the check.
597
+ */
598
+ private effectiveVerifyKey;
599
+ /**
600
+ * Collapse a judge result into a {@link Decision}. The most restrictive
601
+ * signal wins (security review 2026-09-30, H1): `action_type`, `verdict`
602
+ * and the canonical `allow` are each able to deny, and only a result where
603
+ * all three agree may execute. A present `allow` / `decision.allow` that is
604
+ * not exactly `true` is the judge declining to grant permission, so it
605
+ * denies even under `failClosed: false` — that option relaxes *errors*, it
606
+ * never overrides a refusal.
607
+ */
608
+ private decide;
562
609
  /**
563
610
  * One exit for every judge failure.
564
611
  *
@@ -568,6 +615,12 @@ declare class Atbash {
568
615
  * The response body follows only under `debug`, since it can echo the action.
569
616
  */
570
617
  private failJudge;
618
+ /**
619
+ * The canonical permission for a response body under this client's
620
+ * settings: {@link canonicalAllow}, minus the audit tier when
621
+ * `requireEnforcement` is on. Never more permissive than `auditToolCall`.
622
+ */
623
+ private executable;
571
624
  private fail;
572
625
  /**
573
626
  * Return the current status of a previously submitted judgment.
@@ -1111,6 +1164,8 @@ interface GuardMemoryWriteInput extends ClassifyMemoryWriteOptions {
1111
1164
  verifyPubKey?: string;
1112
1165
  /** Org name for chain resolution (public vs org-private chain). */
1113
1166
  orgName?: string;
1167
+ /** Explicit chain target when the host already resolved and verified it. */
1168
+ chainOpts?: ChainOpts;
1114
1169
  /** LLM confidence threshold for yellow escalation. Default 0.6. */
1115
1170
  threshold?: number;
1116
1171
  /** When false, red verdicts log but don't block. Default true. */
@@ -1133,7 +1188,7 @@ interface GuardMemoryWriteResult {
1133
1188
  decision?: GuardMemoryDecision;
1134
1189
  /** Present when handled and scan ran. Absent when scan threw. */
1135
1190
  scanResult?: MemoryScanResult;
1136
- /** Present when handled. True when a chain-commit was dispatched (fire-and-forget). */
1191
+ /** Present when handled. True only after the chain transaction confirms. */
1137
1192
  committed?: boolean;
1138
1193
  }
1139
1194
  /**
@@ -1143,12 +1198,13 @@ interface GuardMemoryWriteResult {
1143
1198
  *
1144
1199
  * Verdict handling:
1145
1200
  * - `red` → not persisted to chain; decision blocks (unless `enforce: false`)
1146
- * - `yellow` → persisted with LLM score; decision allows
1147
- * - `green` → persisted with LLM score; decision allows
1201
+ * - `yellow` → persisted with its LLM score; decision allows once the chain confirms
1202
+ * - `green` → persisted with its LLM score; decision allows once the chain confirms
1203
+ * - anything else → not persisted; decision blocks (unless `enforce: false`)
1148
1204
  *
1149
- * Chain commit is fire-and-forget: network errors are logged via
1150
- * `logger.warn` but never surfaced to the caller. This mirrors the
1151
- * existing plugin behaviour — chain is for audit/recovery, not gating.
1205
+ * A write is acknowledged only after the chain transaction confirms, for
1206
+ * yellow exactly as for green. An unconfirmed write blocks in enforce mode
1207
+ * and remains unaudited in observe mode.
1152
1208
  */
1153
1209
  declare function guardMemoryWrite(input: GuardMemoryWriteInput): Promise<GuardMemoryWriteResult>;
1154
1210
 
@@ -1178,6 +1234,8 @@ interface SyncMemoryOptions {
1178
1234
  /** Skip the TTL gate and force a chain check this call. Default false. */
1179
1235
  force?: boolean;
1180
1236
  chainOpts?: ChainOpts;
1237
+ /** Exact chain slot for the managed file; omission keeps the cross-file API behavior. */
1238
+ filePath?: string;
1181
1239
  }
1182
1240
  /**
1183
1241
  * `drifted: false` — pointer is still valid; caller can keep serving the local copy.
@@ -1226,6 +1284,8 @@ declare function defaultPointerPath(workspaceDir?: string): string;
1226
1284
  interface WrappedLogger {
1227
1285
  info(message: string, meta?: Record<string, unknown>): void;
1228
1286
  warn(message: string, meta?: Record<string, unknown>): void;
1287
+ /** Wait for queued writes and surface any lost log entry. */
1288
+ flush(): Promise<void>;
1229
1289
  }
1230
1290
  interface UpstreamLogger {
1231
1291
  info: (...args: unknown[]) => void;
@@ -1285,10 +1345,10 @@ interface HookDecision {
1285
1345
  * failure, a rolled-back version), and a host must never re-judge its way past
1286
1346
  * one.
1287
1347
  *
1288
- * Absent or false means the guard reached no decision — it was inside its cache
1289
- * window, chain was unreachable, the scan never ran, the file it can vouch for
1290
- * is not the file being read, or it is in observe mode. Those calls are
1291
- * unaudited: fall through to your own judge exactly as for a `null` return.
1348
+ * Absent or false means the guard reached no decision — for example, the scan
1349
+ * never ran or this manager does not own the requested file. In enforce mode,
1350
+ * failed chain verification of the managed file is a block, never an unaudited
1351
+ * allow. In observe mode unverified calls remain unaudited.
1292
1352
  *
1293
1353
  * So the host rule is:
1294
1354
  * `if (d.block) deny; else if (d.audited) allow; else judge it yourself;`
@@ -1388,9 +1448,9 @@ declare class MemoryGuardManager {
1388
1448
  runBootProbe(): Promise<void>;
1389
1449
  /**
1390
1450
  * Returns a `HookDecision` when the guard reached a decision about this event.
1391
- * Returns `null` when it did not — either the event isn't memory-related, or it
1392
- * is but the guard could not check it. In both cases the host falls through to
1393
- * its own audit.
1451
+ * Returns `null` for non-memory events, other files this manager does not
1452
+ * own, or unverified observe-mode reads. An enforced read of the managed
1453
+ * file blocks when verification cannot complete.
1394
1454
  *
1395
1455
  * A returned decision carries `audited` (see `HookDecision`). Only
1396
1456
  * `{ allow: true, audited: true }` means "checked and cleared"; anything else
@@ -1415,6 +1475,9 @@ declare class MemoryGuardManager {
1415
1475
  */
1416
1476
  private vouchesForTarget;
1417
1477
  private handleMemoryRead;
1478
+ /** Complete queued audit-log writes before a host shuts down or removes its workspace. */
1479
+ flushLogs(): Promise<void>;
1480
+ private unverifiedRead;
1418
1481
  private writeMemoryAtomic;
1419
1482
  }
1420
1483
  declare function createMemoryGuardManager(opts: MemoryGuardManagerOptions): MemoryGuardManager;