@orkestrel/agent 0.0.35 → 0.0.37

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.
@@ -1,4 +1,5 @@
1
1
  import { ArrayShape } from '@orkestrel/contract';
2
+ import type { AuditFault } from '@orkestrel/contract';
2
3
  import { BooleanShape } from '@orkestrel/contract';
3
4
  import type { BudgetInterface } from '@orkestrel/budget';
4
5
  import { ContractInterface } from '@orkestrel/contract';
@@ -12,9 +13,11 @@ import type { FileInput } from '@orkestrel/workspace';
12
13
  import type { FileInterface } from '@orkestrel/workspace';
13
14
  import type { Guard } from '@orkestrel/contract';
14
15
  import type { JSONRecord } from '@orkestrel/contract';
16
+ import type { JSONSchema } from '@orkestrel/contract';
15
17
  import { JSONShape } from '@orkestrel/contract';
16
18
  import { JSONValue } from '@orkestrel/contract';
17
19
  import { LiteralShape } from '@orkestrel/contract';
20
+ import { NullableShape } from '@orkestrel/contract';
18
21
  import { NumberShape } from '@orkestrel/contract';
19
22
  import { ObjectShape } from '@orkestrel/contract';
20
23
  import { OptionalShape } from '@orkestrel/contract';
@@ -510,13 +513,16 @@ export declare interface AgentContextOptions {
510
513
  }
511
514
 
512
515
  /**
513
- * Reports an `ask` on an authority that has no approver or that its approver refuses, a run sharing accounting or a conversation with a live run, a `limit` that is not a nonnegative safe integer, a name absent from a registry pool, or a strict run whose request exceeds its window. Agent construction, the `stream` and `generate` methods, and registry accessors throw synchronously, before returning a handle or promise; a `'WINDOW'` refusal rejects the run's `result` instead, and an `'APPROVER'` refusal rejects the promise the `ask` method of an `Authority` or the `ask` handler of an `Approver` returns. Await the call inside `try`/`catch` to catch it.
516
+ * Reports an `ask` on an authority that has no approver or that its approver refuses, an authority missing its fallback or a rule's verdict, tools set with no authority, a run sharing accounting or a conversation with a live run, a `limit` that is not a positive safe integer, a name absent from a registry pool, a strict run's answer that fails its schema, or a strict run whose request exceeds its window. Agent construction, the `stream` and `generate` methods, and registry accessors throw synchronously, before returning a handle or promise; a `'WINDOW'` refusal rejects the run's `result` instead, and an `'APPROVER'` refusal rejects the promise the `ask` method of an `Authority` or the `ask` handler of an `Approver` returns. Await the call inside `try`/`catch` to catch it.
514
517
  *
515
518
  * @remarks
516
519
  * `'APPROVER'` reports an `ask` on an `Authority` built with no `ask` handler, or an ask an
517
520
  * `Approver` refuses: a call framed while no ask waited for it, a second ask for a waiting call, or
518
521
  * arguments it cannot render. The agent loop reads it as an unanswered ask and denies the call. Its
519
522
  * `context` names the asked `tool`.
523
+ * `'AUTHORITY'` reports an `Authority` built with no valid `fallback`, a rule with no valid `verdict`
524
+ * (its `context` names the `rule` index), and an agent built with `tools` and no `authority`. Each
525
+ * throws at construction, with the options a host passes to correct it in the message.
520
526
  * `'CONCURRENCY'` reports a run started while another run on the same agent is live, when the
521
527
  * agent carries a `window` (a shared context budget) or when the run's effective `budget` or
522
528
  * `allowance` is an instance a live run holds — the second run's `start()` would replace that
@@ -525,17 +531,18 @@ export declare interface AgentContextOptions {
525
531
  * `agent` id, and the `conversation` id for a shared conversation. For concurrent runs, use
526
532
  * separate agents, or one agent with no `window`, distinct budget and allowance instances per
527
533
  * run, and a distinct conversation per run.
528
- * `'LIMIT'` reports a construction or per-run `limit` that is not a nonnegative safe integer,
534
+ * `'LIMIT'` reports a construction or per-run `limit` that is not a positive safe integer,
529
535
  * including one a rehydrated job carries into `build`. `'REGISTRY'` reports a rehydration name
530
- * absent from its registry pool, on `provider` / `tool` / `authority` / `scheduler` / `build`;
531
- * its `context` names the `category` and the `name`. `'WINDOW'` reports a `strict` run whose
536
+ * absent from its registry pool, on `provider` / `tool` / `authority` / `scheduler` / `build`,
537
+ * whose `context` names the `category` and the `name`, and a job that names `tools` and no
538
+ * `authority` at `build`, whose `context` names the `tools`. `'WINDOW'` reports a `strict` run whose
532
539
  * complete provider request is still over the `window` budget, equal to its `max` included, after
533
540
  * the one permitted fold or with no fold possible; it settles the run `error` before the provider
534
541
  * is called, and its `context` holds the `agent` id, the measured `consumed`, and the window `max`.
535
542
  * Narrow a caught value with {@link isAgentError} and branch on `error.code`.
536
543
  */
537
544
  export declare class AgentError extends Error {
538
- /** Names the machine-readable condition — `'APPROVER'`: an `ask` on an authority that has no approver, or one its approver refuses; `'CONCURRENCY'`: a run sharing accounting or a conversation with a live run; `'LIMIT'`: a `limit` that is not a nonnegative safe integer; `'REGISTRY'`: a rehydration name absent from its registry pool; `'WINDOW'`: a strict run whose complete request is still over its window budget. */
545
+ /** Names the machine-readable condition — `'APPROVER'`: an `ask` on an authority that has no approver, or one its approver refuses; `'AUTHORITY'`: an authority missing its fallback or a rule's verdict, or tools set with no authority; `'CONCURRENCY'`: a run sharing accounting or a conversation with a live run; `'LIMIT'`: a `limit` that is not a positive safe integer; `'REGISTRY'`: a rehydration name absent from its registry pool; `'WINDOW'`: a strict run whose complete request is still over its window budget. */
539
546
  readonly code: AgentErrorCode;
540
547
  /** Holds the values that locate the failure, such as the `agent` id of a refused run, or `undefined` when none were supplied. */
541
548
  readonly context: Readonly<Record<string, unknown>> | undefined;
@@ -549,8 +556,8 @@ export declare class AgentError extends Error {
549
556
  constructor(code: AgentErrorCode, message: string, options?: CodedErrorOptions);
550
557
  }
551
558
 
552
- /** Names the machine-readable agent approver, concurrency, limit, registry, and window failures. */
553
- export declare type AgentErrorCode = 'APPROVER' | 'CONCURRENCY' | 'LIMIT' | 'REGISTRY' | 'WINDOW';
559
+ /** Names the machine-readable agent approver, authority, concurrency, limit, registry, schema, and window failures. */
560
+ export declare type AgentErrorCode = 'APPROVER' | 'AUTHORITY' | 'CONCURRENCY' | 'LIMIT' | 'REGISTRY' | 'SCHEMA' | 'WINDOW';
554
561
 
555
562
  /**
556
563
  * Maps the push observation surface of an {@link AgentInterface} — the lifecycle, usage, and tool
@@ -608,12 +615,11 @@ export declare type AgentEventMap = {
608
615
  readonly ask: readonly [call: ToolCall, decision: AuthorityDecision];
609
616
  /**
610
617
  * Reports a call denied by scope or authority, before dispatch; `decision` is absent for a scope
611
- * miss, a call whose name no definition advertises this turn, a no-advertisement drop, an evaluate
612
- * throw, an invalid decision, or a cleared call whose tool instance changed before dispatch.
613
- * A turn advertising no tools drops each call with `no tool is advertised in the active scope`.
614
- * Otherwise a call excluded by the tool allow-list, or whose name no definition advertises this
615
- * turn, carries `<tool name> is not in the active scope` and produces a denial tool result and
616
- * message. Authority evaluates only admitted calls that name an advertised definition. `reason` is
618
+ * miss, a call whose name no definition advertises this turn, an evaluate throw, an invalid
619
+ * decision, a call on an agent that holds no authority, or a cleared call whose tool instance
620
+ * changed before dispatch. A call excluded by the tool allow-list, or whose name no definition
621
+ * advertises this turn, a turn advertising no tools included, carries `<tool name> is not in the
622
+ * active scope` and produces a denial tool result and message. Authority evaluates only admitted calls that name an advertised definition. `reason` is
617
623
  * the rule's `deny` reason, the thrown error's text, `invalid decision`, `<tool name> changed after
618
624
  * its decision` for a cleared call whose tool instance changed before dispatch (the model reads the
619
625
  * `denied` note), or `undefined`. A cancel that ends the turn before dispatch emits no such `deny`.
@@ -898,7 +904,7 @@ export declare interface AgentInterface {
898
904
  * A run started while another is live throws an {@link import('./errors.js').AgentError} with
899
905
  * `code: 'CONCURRENCY'` when the agent carries a `window`, when the run's effective
900
906
  * `budget` or `allowance` is an instance a live run holds, or when a live run is bound to the
901
- * run's conversation; a run whose `limit` is not a nonnegative safe
907
+ * run's conversation; a run whose `limit` is not a positive safe
902
908
  * integer throws one with `code: 'LIMIT'`. A `prompt` that `agentPromptContract` refuses, a
903
909
  * `budget` or `allowance` that does not implement `BudgetInterface`, or a `conversation` that
904
910
  * does not implement `ConversationInterface`, throws a `ContractError` with code `'placement'`
@@ -910,7 +916,7 @@ export declare interface AgentInterface {
910
916
  *
911
917
  * @param options - Optional per-run {@link AgentRunOptions} (for example `think`); omitted ⇒ defaults
912
918
  * @returns The settled {@link AgentResult} (`partial: true` when cancelled)
913
- * @throws {AgentError} Thrown when a live run shares the `window`, a budget or allowance instance, or the run's conversation (`code: 'CONCURRENCY'`) or the `limit` is not a nonnegative safe integer (`code: 'LIMIT'`), synchronously before a handle returns.
919
+ * @throws {AgentError} Thrown when a live run shares the `window`, a budget or allowance instance, or the run's conversation (`code: 'CONCURRENCY'`) or the `limit` is not a positive safe integer (`code: 'LIMIT'`), synchronously before a handle returns.
914
920
  * @throws {ContractError} Thrown when the `prompt` is not an exact `AgentPrompt`, the `budget` or `allowance` does not implement `BudgetInterface`, or the `conversation` does not implement `ConversationInterface` (`code: 'placement'`), synchronously before a handle returns.
915
921
  */
916
922
  generate(options?: AgentRunOptions): Promise<AgentResult>;
@@ -922,7 +928,7 @@ export declare interface AgentInterface {
922
928
  * @remarks
923
929
  * Like `generate()`, a run that would share the `window`, a live run's budget or allowance
924
930
  * instance, or a live run's conversation throws an {@link import('./errors.js').AgentError} with
925
- * `code: 'CONCURRENCY'`, an invalid `limit` throws one with `code: 'LIMIT'`, and a `prompt` that
931
+ * `code: 'CONCURRENCY'`, a `limit` that is not a positive safe integer throws one with `code: 'LIMIT'`, and a `prompt` that
926
932
  * `agentPromptContract` refuses, a `budget` or `allowance` that does not implement
927
933
  * `BudgetInterface`, or a `conversation` that does not implement `ConversationInterface` throws a
928
934
  * `ContractError` with code `'placement'`, synchronously — before the
@@ -937,7 +943,7 @@ export declare interface AgentInterface {
937
943
  *
938
944
  * @param options - Optional per-run {@link AgentRunOptions} (for example `think`); omitted ⇒ defaults
939
945
  * @returns A live {@link AgentStreamInterface} handle (events + result + abort)
940
- * @throws {AgentError} Thrown when a live run shares the `window`, a budget or allowance instance, or the run's conversation (`code: 'CONCURRENCY'`) or the `limit` is not a nonnegative safe integer (`code: 'LIMIT'`), synchronously before a handle returns.
946
+ * @throws {AgentError} Thrown when a live run shares the `window`, a budget or allowance instance, or the run's conversation (`code: 'CONCURRENCY'`) or the `limit` is not a positive safe integer (`code: 'LIMIT'`), synchronously before a handle returns.
941
947
  * @throws {ContractError} Thrown when the `prompt` is not an exact `AgentPrompt`, the `budget` or `allowance` does not implement `BudgetInterface`, or the `conversation` does not implement `ConversationInterface` (`code: 'placement'`), synchronously before a handle returns.
942
948
  */
943
949
  stream(options?: AgentRunOptions): AgentStreamInterface;
@@ -950,6 +956,37 @@ export declare interface AgentInterface {
950
956
  abort(reason?: unknown): void;
951
957
  }
952
958
 
959
+ /** Checks a durable agent job exactly at `AgentRegistry.build`. */
960
+ export declare const agentJobContract: ContractInterface<Readonly<{
961
+ provider: string;
962
+ } & {
963
+ messages?: readonly Readonly<{
964
+ role: "assistant" | "system" | "tool" | "user";
965
+ content: string;
966
+ } & {
967
+ calls?: readonly Readonly<{
968
+ id: string;
969
+ name: string;
970
+ arguments: {
971
+ readonly [k: string]: JSONValue;
972
+ };
973
+ } & {}>[];
974
+ call?: string;
975
+ images?: readonly string[];
976
+ thinking?: string;
977
+ }>[];
978
+ system?: string;
979
+ tools?: readonly string[];
980
+ authority?: string;
981
+ scheduler?: string;
982
+ limit?: number;
983
+ timeout?: number;
984
+ budget?: number;
985
+ children?: readonly {
986
+ readonly [k: string]: JSONValue;
987
+ }[];
988
+ }>>;
989
+
953
990
  /**
954
991
  * Reports an {@link AgentInterface} run that ended {@link AgentResult.partial} under a
955
992
  * `partial` policy of `false` (the default) — thrown by an agent-job handler (a
@@ -995,13 +1032,13 @@ export declare class AgentJobError extends Error {
995
1032
  export declare interface AgentJobInput {
996
1033
  /** Names the registry key of the {@link ProviderInterface} the job runs against. */
997
1034
  readonly provider: string;
998
- /** Holds the seed conversation added to the rehydrated agent's context (serializable). */
999
- readonly messages: readonly MessageInput[];
1035
+ /** Holds the seed conversation added to the rehydrated agent's context (serializable). Default: an empty seed. */
1036
+ readonly messages?: readonly MessageInput[];
1000
1037
  /** Holds an optional system prompt seeding the agent's context. */
1001
1038
  readonly system?: string;
1002
- /** Names the registry keys of the values of {@link ToolInterface} loaded into the agent's tool manager. */
1039
+ /** Names the registry keys of the values of {@link ToolInterface} loaded into the agent's tool manager; a non-empty list requires `authority`. */
1003
1040
  readonly tools?: readonly string[];
1004
- /** Names the registry key of an optional {@link AuthorityInterface} policy gate. */
1041
+ /** Names the registry key of the {@link AuthorityInterface} policy gate; required when `tools` names any. */
1005
1042
  readonly authority?: string;
1006
1043
  /** Names the registry key of an optional {@link SchedulerInterface} pacing the loop. */
1007
1044
  readonly scheduler?: string;
@@ -1021,6 +1058,39 @@ export declare interface AgentJobInput {
1021
1058
  readonly children?: readonly AgentJobInput[];
1022
1059
  }
1023
1060
 
1061
+ /**
1062
+ * Describes a durable agent job — the record `AgentRegistry.build` checks exactly, so a misspelled key
1063
+ * refuses instead of running an agent without it.
1064
+ *
1065
+ * @remarks
1066
+ * `children` holds JSON records, because each child crosses this shape at its own `build`. `limit`
1067
+ * reads as a number here and as a positive safe integer at the agent's construction, which owns that
1068
+ * refusal.
1069
+ */
1070
+ export declare const agentJobShape: ObjectShape< {
1071
+ provider: StringShape;
1072
+ messages: OptionalShape<ArrayShape<ObjectShape< {
1073
+ role: LiteralShape<readonly ["system", "user", "assistant", "tool"]>;
1074
+ content: StringShape;
1075
+ calls: OptionalShape<ArrayShape<ObjectShape< {
1076
+ id: StringShape;
1077
+ name: StringShape;
1078
+ arguments: ObjectShape<Record<never, never>, JSONShape>;
1079
+ }, boolean | ContractShape>>>;
1080
+ call: OptionalShape<StringShape>;
1081
+ images: OptionalShape<ArrayShape<StringShape>>;
1082
+ thinking: OptionalShape<StringShape>;
1083
+ }, boolean | ContractShape>>>;
1084
+ system: OptionalShape<StringShape>;
1085
+ tools: OptionalShape<ArrayShape<StringShape>>;
1086
+ authority: OptionalShape<StringShape>;
1087
+ scheduler: OptionalShape<StringShape>;
1088
+ limit: OptionalShape<NumberShape>;
1089
+ timeout: OptionalShape<NumberShape>;
1090
+ budget: OptionalShape<NumberShape>;
1091
+ children: OptionalShape<ArrayShape<ObjectShape<Record<never, never>, JSONShape>>>;
1092
+ }, boolean | ContractShape>;
1093
+
1024
1094
  /**
1025
1095
  * Implements the bounded HTTP calls, validation, and result merging of a judge behind concrete
1026
1096
  * wire seams.
@@ -1031,7 +1101,9 @@ export declare interface AgentJobInput {
1031
1101
  * order. `ask` validates the request before any call, builds every body before the first call so
1032
1102
  * a wire limit refuses the request before inference, and runs the calls one after another, each
1033
1103
  * under its own deadline folded with the caller's signal. A cancel throws a `JudgeAbortError`
1034
- * whose `partial` merges the calls that completed. A transport error reaches the caller unchanged.
1104
+ * whose `partial` merges the calls that completed. A transport error reaches the caller unchanged. An
1105
+ * answer that does not fit its question throws code `PROTOCOL`, and a call whose `read` reports no
1106
+ * usage bills the estimate of its response text.
1035
1107
  *
1036
1108
  * @example Writing a judge wire
1037
1109
  * ```ts
@@ -1201,9 +1273,8 @@ export declare interface AgentOptions {
1201
1273
  * Each turn snapshots the scope's tool allow-list before advertising and checks calls
1202
1274
  * against that list before applying authority. A call whose name no definition advertises is
1203
1275
  * denied the same way, whatever the authority would decide.
1204
- * A reply to a turn advertising no tools ends the run as its answer, records an assistant
1205
- * message without calls, and emits a `deny` event for every dropped call without marking it partial.
1206
- * Other scoped-out calls produce denial tool results and messages, and the loop continues.
1276
+ * Every scoped-out call, one in a turn advertising no tools included, produces a denial tool
1277
+ * result and message and a `deny` event, and the loop continues.
1207
1278
  * A scope change through the context's `apply` method applies the tool allow-list at the next
1208
1279
  * turn's snapshot, which a `turn` listener reaches for the same turn, and the instructions,
1209
1280
  * skills, memos, files, and `select` at the next build or select site: run entry, the pre-first-turn
@@ -1211,7 +1282,7 @@ export declare interface AgentOptions {
1211
1282
  */
1212
1283
  readonly scope?: ScopeInterface;
1213
1284
  /**
1214
- * Caps the tool-iteration turns before the loop stops, as a nonnegative safe integer.
1285
+ * Caps the tool-iteration turns before the loop stops, as a positive safe integer.
1215
1286
  * Thrown as an `AgentError` with code `'LIMIT'` when it is not. Default: `DEFAULT_AGENT_LIMIT`.
1216
1287
  */
1217
1288
  readonly limit?: number;
@@ -1248,14 +1319,14 @@ export declare interface AgentOptions {
1248
1319
  /** Carries an external cancel; its abort commits a partial result. */
1249
1320
  readonly signal?: AbortSignal;
1250
1321
  /**
1251
- * Holds an optional policy gate consulted after scope admits a tool call — a denied call is
1322
+ * Holds the policy gate consulted after scope admits a tool call — a denied call is
1252
1323
  * fed back to the model as a denial {@link ToolResult} (a `tool` chunk + a tool
1253
1324
  * message) rather than executed (no tool execution), so the model receives the
1254
1325
  * denial and can react; an allowed call dispatches normally, and an asked call dispatches only
1255
1326
  * when the authority's `ask` approves it. The loop raises an `allow` for a tool whose advertised
1256
- * definition is annotated `consequential` to an `ask`, with or without this option. Omitted ⇒ a
1257
- * default `Authority` with no rules and no approver: an unannotated call dispatches with an
1258
- * `allow` in zone `'default'`, and a `consequential` call is denied as unanswered.
1327
+ * definition is annotated `consequential` to an `ask`. Required when `tools` is set: construction
1328
+ * throws an `AgentError` coded `'AUTHORITY'` otherwise. Omitted with no `tools` ⇒ no gate, and a
1329
+ * tool added later through `context.tools` is denied rather than run.
1259
1330
  */
1260
1331
  readonly authority?: AuthorityInterface;
1261
1332
  /**
@@ -1293,10 +1364,12 @@ export declare interface AgentOptions {
1293
1364
  * still finds over the window, equal to `max` included, after the one permitted fold, or that
1294
1365
  * cannot fold, is refused before the provider is called: the run settles `error` with an
1295
1366
  * `AgentError` coded `'WINDOW'` whose `context` holds the `agent`, the measured `consumed`, and
1296
- * the window `max`, and no `fault` fires for it. If `false`, the run continues — over-window
1297
- * after a summarizer failure or a futile fold, and on the run's conversation's `view()` after a
1298
- * selection fault. A cancel at a selection site or a fold, a `fault` listener's included, settles
1299
- * partial instead of `error`. Default: `false`.
1367
+ * the window `max`, and no `fault` fires for it. A final answer that misses the run's `schema`
1368
+ * settles `error` with an `AgentError` coded `'SCHEMA'`. If `false`, the run continues —
1369
+ * over-window after a summarizer failure or a futile fold, on the run's conversation's `view()`
1370
+ * after a selection fault, and with the raw content after a schema miss, which emits `fault`. A
1371
+ * cancel at a selection site or a fold, a `fault` listener's included, settles partial instead of
1372
+ * `error`. Default: `true`.
1300
1373
  */
1301
1374
  readonly strict?: boolean;
1302
1375
  /**
@@ -1346,7 +1419,8 @@ images: OptionalShape<ArrayShape<StringShape>>;
1346
1419
  * have no size limit. A qwen3 implicit-open reclassification corrects the final
1347
1420
  * content while content deltas already yielded cannot be recalled. A subclass fills
1348
1421
  * `name`, `frame`, `encode`, `read`, and `finish`; the constructor takes the `split`
1349
- * and `strict` switches to control reasoning separation and settled-result requirements.
1422
+ * and `strict` switches to control reasoning separation and whether a stream must end with a settled
1423
+ * `result` or a `done` record, which it must by default.
1350
1424
  * The `replay` input names which stored thinking the agent and relay send back. Default: `'none'`.
1351
1425
  * A throw from the framing seam (`parse`, or `finish`) becomes a `ProviderError` with the
1352
1426
  * `PROTOCOL` code whose `cause` is the throw, unless it is already a `ProviderError` or
@@ -1378,7 +1452,8 @@ images: OptionalShape<ArrayShape<StringShape>>;
1378
1452
  * class TextProvider extends AgentProvider<string> {
1379
1453
  * readonly name = 'text'
1380
1454
  * constructor(options: TextOptions) {
1381
- * super({ ...options, path: '/generate' })
1455
+ * // Raw text has no terminal record, so a stream that stops reads as complete.
1456
+ * super({ ...options, path: '/generate', strict: false })
1382
1457
  * }
1383
1458
  * frame(): ProviderParserInterface<string> {
1384
1459
  * return new TextFrame()
@@ -1443,8 +1518,9 @@ export declare abstract class AgentProvider<TRecord = Readonly<Record<string, un
1443
1518
  * @remarks
1444
1519
  * `path` appends to `url`. If `split` is true, separates in-content reasoning;
1445
1520
  * if false, preserves content verbatim. Default: true.
1446
- * If `strict` is true, requires a settled result record; if false, assembles at end of input.
1447
- * Default: false.
1521
+ * If `strict` is true, a stream that ends with neither a settled `result` nor a `done` record throws
1522
+ * a `ProviderError` with the `PROTOCOL` code, because it was cut; if false, assembles at end of input,
1523
+ * which a wire with no terminal record passes. Default: true.
1448
1524
  */
1449
1525
  export declare interface AgentProviderInput extends ProviderOptions {
1450
1526
  readonly url: string;
@@ -1509,13 +1585,14 @@ export declare interface AgentQueueOptions {
1509
1585
  * rehydrated job is a programmer / config error that must fail loudly at build time, never
1510
1586
  * silently resolve to `undefined` and run an agent missing a dependency.
1511
1587
  * - **`build` rehydrates.** Resolve the job's `provider`; assemble a fresh
1512
- * {@link ToolManager} from the `tools` names; rebuild the token `budget` from its
1588
+ * {@link ToolManager} from the `tools` names, which refuses with `code: 'REGISTRY'` when the job
1589
+ * names no `authority`; rebuild the token `budget` from its
1513
1590
  * ceiling (`createTokenBudget({ max })`); resolve the optional `authority` /
1514
1591
  * `scheduler` names; construct the {@link Agent} with `system` / `limit` / `timeout` /
1515
1592
  * the threaded `signal`; seed its context with the job's `messages`; return it. The
1516
1593
  * `signal` is the queue attempt's / runner unit's cancel, so a bounded abort propagates
1517
1594
  * into the agent (which commits a partial — the job's `partial` policy then
1518
- * decides success vs. retry). A job `limit` that is not a nonnegative safe integer throws an
1595
+ * decides success vs. retry). A job `limit` that is not a positive safe integer throws an
1519
1596
  * {@link AgentError} carrying `code: 'LIMIT'` from the agent's construction.
1520
1597
  * - **Event-free.** A pure resolver — no Emitter, no events.
1521
1598
  *
@@ -1598,7 +1675,7 @@ export declare interface AgentRegistryInterface {
1598
1675
  * @param input - The serializable {@link AgentJobInput} to rehydrate
1599
1676
  * @param signal - An optional cancel threaded into the agent (a queue / runner abort)
1600
1677
  * @returns The ready agent, its context seeded with the job's messages
1601
- * @throws {AgentError} Thrown when a referenced provider, tool, authority, or scheduler name is unregistered (`code: 'REGISTRY'`), or when the job's `limit` is not a nonnegative safe integer (`code: 'LIMIT'`)
1678
+ * @throws {AgentError} Thrown when a referenced provider, tool, authority, or scheduler name is unregistered, or the job names `tools` and no `authority` (`code: 'REGISTRY'`), or when the job's `limit` is not a nonnegative safe integer (`code: 'LIMIT'`)
1602
1679
  * @throws {ConversationError} Thrown when a seed message's role is not a `ConversationRole` (`code: 'ROLE'`), before the agent is returned
1603
1680
  */
1604
1681
  build(input: AgentJobInput, signal?: AbortSignal): AgentInterface;
@@ -1640,7 +1717,7 @@ export declare interface AgentRegistryOptions {
1640
1717
  * holding unresolved tool intent (the model requested tools on the very last allowed
1641
1718
  * turn) — a distinct, non-cancel cause covered by {@link AgentRunResult.exhausted} (see
1642
1719
  * the `exhaust` {@link AgentEventMap} event). It is `false` for a turn that ran to a
1643
- * natural finish (including a `limit: 0` run, which never enters the loop). `usage` is
1720
+ * natural finish. `usage` is
1644
1721
  * present only when at least one provider call or selection reported usage — an aborted run's `usage`
1645
1722
  * includes the cancelled turn's tokens when the provider reports partial usage on the
1646
1723
  * abort (folded in exactly like a completed turn's); a provider that cannot observe
@@ -1702,16 +1779,16 @@ export declare function agentResultToFrame(result: AgentResult): Extract<AgentFr
1702
1779
  /**
1703
1780
  * Projects an unknown value onto a fresh, exact `JSONValue` representation of an
1704
1781
  * {@link AgentResult} — capturing each structural field once through a total boundary,
1705
- * accepting conforming accessors and inherited properties, preserving finite negative and
1706
- * fractional usage counts, dropping extras, and resolving `undefined` for a malformed field, a
1707
- * non-finite usage number, a throwing getter, or a malformed or revoked proxy.
1782
+ * accepting conforming accessors and inherited properties, preserving fractional usage counts,
1783
+ * dropping extras, and resolving `undefined` for a malformed field, a negative or non-finite usage
1784
+ * number, a throwing getter, or a malformed or revoked proxy.
1708
1785
  *
1709
1786
  * @remarks
1710
1787
  * This is a total projection that reads untrusted input. Each structural field is captured once
1711
1788
  * through Contract's sanctioned exception boundary, so conforming accessors and inherited
1712
1789
  * properties are supported while a throwing getter or revoked proxy returns `undefined`.
1713
- * Present usage counts must be finite numbers; negative and fractional values are preserved,
1714
- * not normalized. The result is exact `{ content, thinking?, usage?, partial, stop? }`. A present
1790
+ * Present usage counts must be finite and nonnegative; fractional values are preserved, not
1791
+ * normalized. The result is exact `{ content, thinking?, usage?, partial, stop? }`. A present
1715
1792
  * `stop` is read once, then its `layer`, `id`, `max`, `consumed`, `estimate`, and `usage` once each
1716
1793
  * in that order, `max` and `consumed` only on a `meter` or `budget` arm; the arm is rebuilt
1717
1794
  * exactly, omitting absent readings, and a malformed `stop` refuses the whole value. Extra input
@@ -1776,13 +1853,18 @@ export declare interface AgentRunOptions {
1776
1853
  readonly think?: boolean;
1777
1854
  /**
1778
1855
  * Constrains the response to this JSON-Schema shape, forwarded to the provider's `stream`
1779
- * as {@link ProviderStreamOptions.schema} — a per-run structured-output request. Omitted ⇒
1780
- * no constraint (the loop sends no schema).
1856
+ * as {@link ProviderStreamOptions.schema} — a per-run structured-output request, and enforced: the
1857
+ * final answer must parse as JSON and satisfy the schema, through the lenient `schemaToShape`. A
1858
+ * miss under {@link AgentOptions.strict} settles the run `error` with an `AgentError` coded
1859
+ * `'SCHEMA'` whose `context` holds the `faults` and stores no answer; under `strict: false` it emits
1860
+ * `fault` with that error and settles with the raw content, the opt-out for a provider that ignores
1861
+ * schemas. A `truncated` answer skips the check and keeps its `model` stop. Omitted ⇒ no constraint
1862
+ * (the loop sends no schema).
1781
1863
  */
1782
1864
  readonly schema?: Readonly<Record<string, unknown>>;
1783
1865
  /**
1784
1866
  * Overrides {@link AgentOptions.limit} for this run only — the max tool-iteration turns
1785
- * before the loop stops, as a nonnegative safe integer; the call throws an `AgentError` with
1867
+ * before the loop stops, as a positive safe integer; the call throws an `AgentError` with
1786
1868
  * code `'LIMIT'` when it is not. Omitted ⇒ the agent's constructed `limit` applies.
1787
1869
  */
1788
1870
  readonly limit?: number;
@@ -1925,7 +2007,11 @@ export declare type AgentStreamInterface = StreamInterface<AgentChunk, AgentResu
1925
2007
  * @example
1926
2008
  * ```ts
1927
2009
  * const approver = createApprover()
1928
- * const authority = createAuthority({ rules, ask: approver.ask })
2010
+ * const authority = createAuthority({
2011
+ * rules,
2012
+ * fallback: { zone: 'default', verdict: 'deny' },
2013
+ * ask: approver.ask,
2014
+ * })
1929
2015
  * const agent = createAgent(provider, { tools, authority })
1930
2016
  * for await (const frame of agentStreamToFrames(agent.stream({ prompt }), approver)) {
1931
2017
  * send(JSON.stringify(frame))
@@ -1993,7 +2079,11 @@ export declare interface AnswerMeasure {
1993
2079
  * @example
1994
2080
  * ```ts
1995
2081
  * const approver = new Approver()
1996
- * const authority = createAuthority({ rules, ask: approver.ask })
2082
+ * const authority = createAuthority({
2083
+ * rules,
2084
+ * fallback: { zone: 'default', verdict: 'deny' },
2085
+ * ask: approver.ask,
2086
+ * })
1997
2087
  * approver.answer({ id, approved: true }) // true while that ask waits
1998
2088
  * ```
1999
2089
  */
@@ -2112,13 +2202,14 @@ export declare function attachImages(message: Message, payloads: readonly string
2112
2202
  * @remarks
2113
2203
  * Pure and total: the conversation and its messages are never mutated, and the returned array
2114
2204
  * replaces exactly the one target message with the copy {@link attachImages} builds. Empty
2115
- * data returns the conversation unchanged; a conversation with no user message returns it
2116
- * unchanged too (there is nowhere to attach, so the images are left out). A hole
2117
- * in a sparse conversation is not a user message.
2205
+ * data returns the conversation unchanged. Data with no user message to carry it refuses, an empty
2206
+ * conversation included, because leaving the images out would run without them. A hole in a sparse
2207
+ * conversation is not a user message.
2118
2208
  *
2119
2209
  * @param conversation - The messages to attach into (left unchanged)
2120
2210
  * @param payloads - The base64 image data to attach
2121
2211
  * @returns The conversation with its last user message replaced by the carrying copy
2212
+ * @throws ContextError Thrown when there is data and no user message to carry it (code `'IMAGES'`)
2122
2213
  *
2123
2214
  * @example
2124
2215
  * ```ts
@@ -2131,19 +2222,18 @@ export declare function attachUserImages(conversation: readonly Message[], paylo
2131
2222
  /**
2132
2223
  * Gates the agent loop's tool calls — the synchronous policy consulted before each call runs,
2133
2224
  * turning one {@link AuthorityContext} into an {@link AuthorityDecision} by walking the ordered
2134
- * rules first-match-wins and falling back to a configurable default, which allows an unmatched
2135
- * call unless its `fallback` decides otherwise, and the approver that answers an `ask` verdict.
2225
+ * rules first-match-wins and falling back to the required `fallback`, and the approver that answers
2226
+ * an `ask` verdict.
2136
2227
  *
2137
2228
  * @remarks
2229
+ * - **Refuses at construction.** The constructor throws an `AgentError` coded `'AUTHORITY'` when the
2230
+ * `fallback` is missing or malformed, or when a rule has no valid `verdict`, so a policy with a
2231
+ * hole in it never runs.
2138
2232
  * - **Ordered, first-match-wins.** `evaluate` walks the configured rules in order and
2139
- * returns the first whose `match(context)` is true as
2140
- * `{ zone, verdict: rule.verdict ?? 'allow', reason }` — a matched rule with no `verdict`
2141
- * allows.
2142
- * - **Fallback.** When no rule matches, `evaluate` returns the configured `fallback`.
2143
- * Default: `{ zone: DEFAULT_AUTHORITY_ZONE, verdict: 'allow' }` (allow-unmatched),
2144
- * so a rules list of denials behaves as a denylist. To make the gate deny-by-default
2145
- * (an allowlist — only matched rules that allow get through), pass a `verdict: 'deny'`
2146
- * `fallback`.
2233
+ * returns the first whose `match(context)` is true as `{ zone, verdict, reason }`.
2234
+ * - **Fallback.** When no rule matches, `evaluate` returns the configured `fallback`: a
2235
+ * `verdict: 'deny'` fallback makes an allowlist (only matched rules that allow get through), and a
2236
+ * `verdict: 'allow'` fallback makes a denylist.
2147
2237
  * - **Consulted before each tool call.** The agent loop calls `evaluate({ call })` for
2148
2238
  * every {@link import('@orkestrel/tool').ToolCall} the model emits; a denied call is fed
2149
2239
  * back to the model as a denial {@link import('@orkestrel/tool').ToolResult} (a `tool`
@@ -2158,9 +2248,10 @@ export declare function attachUserImages(conversation: readonly Message[], paylo
2158
2248
  *
2159
2249
  * @example
2160
2250
  * ```ts
2161
- * // A denylist: deny the `delete` tool, allow everything else (default fallback).
2251
+ * // A denylist: deny the `delete` tool, allow everything else.
2162
2252
  * const authority = new Authority({
2163
2253
  * rules: [{ match: (c) => c.call.name === 'delete', zone: 'restricted', verdict: 'deny' }],
2254
+ * fallback: { zone: 'default', verdict: 'allow' },
2164
2255
  * })
2165
2256
  * authority.evaluate({ call: { id: '1', name: 'delete', arguments: {} } }) // { zone: 'restricted', verdict: 'deny' }
2166
2257
  * authority.evaluate({ call: { id: '2', name: 'add', arguments: {} } }) // { zone: 'default', verdict: 'allow' }
@@ -2168,7 +2259,7 @@ export declare function attachUserImages(conversation: readonly Message[], paylo
2168
2259
  */
2169
2260
  export declare class Authority implements AuthorityInterface {
2170
2261
  #private;
2171
- constructor(options?: AuthorityOptions);
2262
+ constructor(options: AuthorityOptions);
2172
2263
  evaluate(context: AuthorityContext): AuthorityDecision;
2173
2264
  ask(context: AuthorityContext, decision: AuthorityDecision, signal: AbortSignal): Promise<boolean>;
2174
2265
  }
@@ -2227,7 +2318,7 @@ export declare type AuthorityHandler = (context: AuthorityContext, decision: Aut
2227
2318
  export declare interface AuthorityInterface {
2228
2319
  /**
2229
2320
  * Evaluates one tool call against the ordered rules — returns the first matching rule's
2230
- * verdict, which allows when the rule names none, or the fallback when none match.
2321
+ * verdict, or the fallback when none match.
2231
2322
  *
2232
2323
  * @param context - The call under consideration (see {@link AuthorityContext})
2233
2324
  * @returns The first matching rule's verdict, or the fallback when none match
@@ -2256,16 +2347,14 @@ export declare interface AuthorityNote {
2256
2347
  *
2257
2348
  * @remarks
2258
2349
  * `rules` are evaluated in order, first match wins (see {@link AuthorityRule}).
2259
- * `fallback` is the {@link AuthorityDecision} returned when no rule matches.
2260
- * Default: `{ zone: DEFAULT_AUTHORITY_ZONE, verdict: 'allow' }` (allow-unmatched — a
2261
- * rules list of denials acts as a denylist). Set `fallback` to a `verdict: 'deny'`
2262
- * decision to flip the gate to deny-by-default (an allowlist — only matched rules
2263
- * that allow get through). `ask` is the {@link AuthorityHandler} that answers each `ask`
2264
- * verdict; absent, every ask is refused as unanswered.
2350
+ * `fallback` is the {@link AuthorityDecision} returned when no rule matches, and it is required:
2351
+ * a `verdict: 'deny'` fallback makes an allowlist (only matched rules that allow get through), and a
2352
+ * `verdict: 'allow'` fallback makes a denylist. `ask` is the {@link AuthorityHandler} that answers
2353
+ * each `ask` verdict; absent, every ask is refused as unanswered.
2265
2354
  */
2266
2355
  export declare interface AuthorityOptions {
2267
2356
  readonly rules?: readonly AuthorityRule[];
2268
- readonly fallback?: AuthorityDecision;
2357
+ readonly fallback: AuthorityDecision;
2269
2358
  readonly ask?: AuthorityHandler;
2270
2359
  }
2271
2360
 
@@ -2274,13 +2363,14 @@ export declare interface AuthorityOptions {
2274
2363
  *
2275
2364
  * @remarks
2276
2365
  * The first rule whose `match` returns true decides; if none match, the authority's
2277
- * `fallback` decides. A matched rule with no `verdict` allows. `zone` classifies the matched
2278
- * call; `reason` is the optional explanation carried into the {@link AuthorityDecision}.
2366
+ * `fallback` decides. `zone` classifies the matched call; `verdict` is required, and an
2367
+ * `Authority` refuses a rule with none at construction; `reason` is the optional explanation
2368
+ * carried into the {@link AuthorityDecision}.
2279
2369
  */
2280
2370
  export declare interface AuthorityRule {
2281
2371
  readonly match: (context: AuthorityContext) => boolean;
2282
2372
  readonly zone: string;
2283
- readonly verdict?: AuthorityVerdict;
2373
+ readonly verdict: AuthorityVerdict;
2284
2374
  readonly reason?: string;
2285
2375
  }
2286
2376
 
@@ -2368,6 +2458,17 @@ export declare function buildLedgerCut(steps: ReadonlyArray<LedgerLine | string>
2368
2458
  */
2369
2459
  export declare function buildLedgerIndex(registry: LedgerRegistry): LedgerIndex;
2370
2460
 
2461
+ /**
2462
+ * Encodes a sentence's record placement without comparing rendered text.
2463
+ * @param line - The record key, title, source, and zero-based sentence index
2464
+ * @returns The serialized placement identity
2465
+ * @example
2466
+ * ```ts
2467
+ * buildLedgerLineKey({ key: 'rules', title: 'Rules', source: 'one', sentence: 0 })
2468
+ * ```
2469
+ */
2470
+ export declare function buildLedgerLineKey(line: Pick<LedgerOccurrence, 'key' | 'title' | 'source' | 'sentence'>): string;
2471
+
2371
2472
  /**
2372
2473
  * Derives complete source identities, first occurrences, and local references from the actual lines of the records.
2373
2474
  * @param messages - Original messages whose indexed sentences establish completeness
@@ -2484,17 +2585,17 @@ export declare function buildRecapMessage(section: Section): Message;
2484
2585
  * Projects the owner records and the rules record from a conversation's messages.
2485
2586
  *
2486
2587
  * @remarks
2487
- * Each line is a sentence of a live message, verbatim except that a sentence that opens with a pronoun opens with its party and a colon. A message is live when it is a user message,
2488
- * or a tool message whose finding is the last finding of its call, and the input neither excludes it nor
2489
- * files it quiet or replaced. A finding with an undefined `result` still replaces the earlier
2490
- * finding of the same call, so the earlier result leaves every record.
2588
+ * Each line is a sentence of a live message, verbatim except that a sentence that opens with a
2589
+ * pronoun opens with its party and a colon. {@link collectLive} retains user messages and the
2590
+ * earliest finding in each call identity's last run of identical text, subject to exclusions,
2591
+ * quiet classification, and supersessions. An undefined result still replaces the earlier finding.
2491
2592
  *
2492
2593
  * A live message joins the owner records its entities name, directly or through a linked lookup
2493
2594
  * argument. A message that names no owner joins where its earlier side of an amendment pair joins,
2494
2595
  * or on the rules record when it is filed as a rule or a correction, and is an orphan otherwise.
2495
2596
  *
2496
- * Every live sentence is retained. Accepted direct edges are listed in `amendments`. An amending message
2497
- * that is itself superseded retains its accepted edge without restoring its text.
2597
+ * Every live sentence is retained. Accepted edges are listed in `amendments`. An amender that is
2598
+ * superseded points to its newest live successor, or retains its endpoint when none exists.
2498
2599
  *
2499
2600
  * A sentence that opens with a pronoun takes the party named in the sentence before it. The reading
2500
2601
  * trusts capitals, so a capitalized word that is no person, such as a carrier named mid-sentence,
@@ -2740,19 +2841,19 @@ export declare class Classifier implements ClassifierInterface {
2740
2841
  * Asks the judge every question the filing still lacks, in the measured order.
2741
2842
  * @param requests - The request ids, which skip category questions and receive only enabled request-topic questions
2742
2843
  * @param signal - The caller's signal; an abort returns a fault with completed judgments and usage
2743
- * @returns The judgment keys, summed usage, and one attempt per logical question, in asking order; a throw from the assign or entities handler, a scheduler rejection, or a caller abort returns the partial result with `fault`; a judge rejection under a live signal leaves that question undecided and sets no `fault`
2844
+ * @returns The judgment keys, summed usage, and one attempt per logical question, in asking order; a throw from the assign or entities handler, a scheduler rejection, or a caller abort returns the partial result with `fault`; a judge rejection under a live signal leaves that question undecided and sets `failure`
2744
2845
  */
2745
2846
  classify(requests: ReadonlySet<string>, signal: AbortSignal): Promise<ClassifierResult>;
2746
2847
  /**
2747
2848
  * Reads the category a message is filed under.
2748
2849
  * @param id - The message id
2749
- * @returns The assigned category, the recorded category at the cutoff, or `undefined`
2850
+ * @returns The assigned category, the recorded category at the cutoff, or `undefined`; a quiet winner suppressed by the user literal floor remains undecided
2750
2851
  */
2751
2852
  category(id: string): LedgerCategory | undefined;
2752
2853
  /**
2753
2854
  * Reports whether a message files under a quiet category.
2754
2855
  * @param id - The message id
2755
- * @returns True if the assigned or recorded category is quiet; false otherwise.
2856
+ * @returns True if the assigned category is quiet or the recorded quiet weight reaches the cutoff, except for a user message carrying an id or number; false otherwise
2756
2857
  */
2757
2858
  quiet(id: string): boolean;
2758
2859
  /**
@@ -2805,18 +2906,18 @@ export declare interface ClassifierInterface {
2805
2906
  *
2806
2907
  * @param requests - The request ids, which skip category questions and receive only enabled request-topic questions
2807
2908
  * @param signal - The signal that aborts the questions; completed judgments stay recorded
2808
- * @returns The judgment keys, usage spent, and one attempt per logical question; a throw from the assign or entities handler, a scheduler rejection, or a caller abort returns the partial result with `fault`; a judge rejection under a live signal leaves that question undecided and sets no `fault`
2909
+ * @returns The judgment keys, usage spent, and one attempt per logical question; a throw from the assign or entities handler, a scheduler rejection, or a caller abort returns the partial result with `fault`; a judge rejection under a live signal leaves that question undecided and sets `failure`
2809
2910
  */
2810
2911
  classify(requests: ReadonlySet<string>, signal: AbortSignal): Promise<ClassifierResult>;
2811
2912
  /**
2812
- * Returns the category a message is filed under, or undefined when no category reaches its cutoff.
2913
+ * Returns the assigned or recorded category, or undefined when no category reaches its cutoff or the user literal floor suppresses a quiet winner.
2813
2914
  *
2814
2915
  * @param id - The id of the message
2815
2916
  * @returns The category, or undefined
2816
2917
  */
2817
2918
  category(id: string): LedgerCategory | undefined;
2818
2919
  /**
2819
- * Returns true if the message is filed as quiet; false otherwise.
2920
+ * Returns true for a quiet assignment or a recorded quiet weight at the cutoff, except for a user message carrying an id or number; false otherwise.
2820
2921
  *
2821
2922
  * @param id - The id of the message
2822
2923
  * @returns True if the message is quiet; false otherwise.
@@ -2861,6 +2962,8 @@ export declare interface ClassifierInterface {
2861
2962
  * no scheduler, the call takes no host turn and reads no added clock.
2862
2963
  */
2863
2964
  export declare interface ClassifierOptions {
2965
+ /** Sets what a refused question or a deterministic judge failure leaves behind. Default `true`: nothing, so the next call asks again. `false` holds the question, so no later call asks it. */
2966
+ readonly strict?: boolean;
2864
2967
  readonly conversation: ConversationInterface;
2865
2968
  readonly judge: JudgeInterface;
2866
2969
  readonly questions: LedgerQuestion;
@@ -2877,7 +2980,7 @@ export declare interface ClassifierOptions {
2877
2980
  *
2878
2981
  * @remarks
2879
2982
  * `cached` means the conversation already held a matching judgment, so the classifier did not call the judgment manager.
2880
- * `skipped` means the classifier held the question, after a deterministic failure or because a message it names left the conversation, and did not call the judgment manager.
2983
+ * `skipped` means the classifier held the question, after a deterministic failure under `strict: false` or because a message it names left the conversation, and did not call the judgment manager.
2881
2984
  * `resolved` means the judgment manager's resolve call fulfilled. `failed` means it rejected while the caller's signal was live.
2882
2985
  * `aborted` means it rejected with a `JudgeAbortError` or after the caller's signal aborted.
2883
2986
  */
@@ -2899,6 +3002,8 @@ export declare interface ClassifierResult {
2899
3002
  readonly attempts: readonly ClassifierAttempt[];
2900
3003
  /** Holds the error when an assign or entities handler throw, a scheduler rejection, or a caller abort interrupts classification; judgments and usage retain the partial result. A judge rejection under a live signal sets no fault. */
2901
3004
  readonly fault?: Error;
3005
+ /** Holds the first judge rejection of this call under a live signal: that question stays undecided and the filing goes on, so the result is whole but for it. A question held from an earlier call reports nothing. */
3006
+ readonly failure?: Error;
2902
3007
  }
2903
3008
 
2904
3009
  /**
@@ -2915,17 +3020,18 @@ export declare interface CodedErrorOptions {
2915
3020
  }
2916
3021
 
2917
3022
  /**
2918
- * Collects accepted direct amendments of live messages.
3023
+ * Collects accepted amendments of live messages, following superseded amenders to live successors.
2919
3024
  *
2920
3025
  * @remarks
2921
3026
  * An accepted edge relates an earlier live message to an amender without claiming which sentences
2922
- * changed. An amender takes effect while live and retains its edge after another message supersedes
2923
- * it, without restoring the superseded text. An excluded or quiet user or tool message has no effect.
3027
+ * changed. A superseded amender points to its newest reachable live successor in conversation order,
3028
+ * with cycles guarded and duplicate endpoints removed. With no live successor, its endpoint stays.
3029
+ * This never restores superseded text. An excluded or quiet user or tool message has no effect.
2924
3030
  *
2925
3031
  * @param input - The exclusions and classification to read
2926
3032
  * @param byId - The messages by id
2927
3033
  * @param live - The live message ids from {@link collectLive}
2928
- * @returns The distinct accepted direct edges in conversation order
3034
+ * @returns The distinct accepted edges in conversation order
2929
3035
  *
2930
3036
  * @example
2931
3037
  * ```ts
@@ -2973,15 +3079,54 @@ export declare function collectExchanges(messages: readonly Message[]): Readonly
2973
3079
  */
2974
3080
  export declare function collectImageData(files: readonly FileInterface[]): readonly string[];
2975
3081
 
3082
+ /**
3083
+ * Captures source bytes and direct amendment edges for a held window.
3084
+ * @param messages - Current stored messages
3085
+ * @param sources - Requests, replies, and record sources the window holds
3086
+ * @param amendments - Accepted direct amendment edges from the current projection
3087
+ * @returns Source and edge identities for stale detection
3088
+ * @example
3089
+ * ```ts
3090
+ * collectLedgerEvidence([], new Set(), []).messages.size // 0
3091
+ * ```
3092
+ */
3093
+ export declare function collectLedgerEvidence(messages: readonly Message[], sources: ReadonlySet<string>, amendments: readonly LedgerAmendment[]): LedgerEvidence;
3094
+
3095
+ /**
3096
+ * Collects the record's sentence receipts not already held by a window.
3097
+ * @param record - The selected record with its original sentence identities
3098
+ * @param held - Placement identities already rendered in the window
3099
+ * @returns The remaining sentences with their record placement
3100
+ * @example
3101
+ * ```ts
3102
+ * collectLedgerLines({ key: 'rules', title: 'Rules', members: [], lines: [] }, new Set()) // []
3103
+ * ```
3104
+ */
3105
+ export declare function collectLedgerLines(record: LedgerRecord, held: ReadonlySet<string>): readonly LedgerOccurrence[];
3106
+
3107
+ /**
3108
+ * Selects each marked request's unambiguous final call-free reply.
3109
+ * @param messages - Stored conversation messages in order
3110
+ * @param requests - Marked request ids delimiting reply intervals
3111
+ * @param notes - Ledger notes that separate answer passes
3112
+ * @returns Eligible final replies keyed by request id
3113
+ * @example
3114
+ * ```ts
3115
+ * collectLedgerReplies([], new Set(), new Set()).size // 0
3116
+ * ```
3117
+ */
3118
+ export declare function collectLedgerReplies(messages: readonly Message[], requests: ReadonlySet<string>, notes: ReadonlySet<string>): ReadonlyMap<string, Message>;
3119
+
2976
3120
  /**
2977
3121
  * Collects the ids of the live messages in conversation order.
2978
3122
  *
2979
3123
  * @remarks
2980
- * A message is live when it is a user message, or a tool message whose finding is the last finding of its
2981
- * call, and the input neither excludes it nor files it quiet or replaced. A finding replaces any
2982
- * earlier finding of the same call, an empty one included, so an empty lookup leaves the earlier
2983
- * result out of every record. A finding with no canonical identity stays live as its own source
2984
- * and participates in no replacement.
3124
+ * A message is live when it is a user message or the first unsuperseded finding in its canonical
3125
+ * call identity's last run of identical text, and the input neither excludes it nor files it quiet
3126
+ * or superseded. When the whole run is superseded, its first finding reaches that final filter.
3127
+ * Different text or an undefined result replaces the earlier run, so an empty lookup leaves the
3128
+ * earlier result out of every record. A thrown lookup leaves the earlier result live. A finding
3129
+ * with no canonical identity participates in no replacement.
2985
3130
  *
2986
3131
  * @param input - The messages, findings, and classification to read
2987
3132
  * @returns The live message ids
@@ -3021,6 +3166,22 @@ export declare function collectNames(text: string): readonly string[];
3021
3166
  */
3022
3167
  export declare function collectProjectionIds(projection: LedgerProjection): ReadonlySet<string>;
3023
3168
 
3169
+ /**
3170
+ * Collects stored messages eligible to open the recall offer.
3171
+ * @remarks
3172
+ * Notes and findings without a result do not open the offer. User statements, including quiet
3173
+ * statements available through recall's word route, can open it; this helper does not filter results.
3174
+ * @param input - The messages, findings, and classification
3175
+ * @param requests - The marked request ids
3176
+ * @param notes - The annotation ids to exclude
3177
+ * @returns User statements, lookup findings with results, marked requests, and nonblank call-free replies
3178
+ * @example
3179
+ * ```ts
3180
+ * collectRecallMessages(input, new Set(), new Set()) // eligible stored messages
3181
+ * ```
3182
+ */
3183
+ export declare function collectRecallMessages(input: LedgerProjectionInput, requests: ReadonlySet<string>, notes: ReadonlySet<string>): readonly Message[];
3184
+
3024
3185
  /**
3025
3186
  * Collects the ids and the owner names the lookup findings named.
3026
3187
  *
@@ -3115,18 +3276,21 @@ export declare function computeThinking(message: Pick<Message, 'thinking' | 'con
3115
3276
 
3116
3277
  /**
3117
3278
  * Reports a context snapshot that `isMemoSnapshot` refuses, thrown by the construction of a
3118
- * {@link import('./memos/MemoManager.js').MemoManager} before it seats any state, carrying the
3119
- * machine-readable `code` `'SNAPSHOT'`.
3279
+ * {@link import('./memos/MemoManager.js').MemoManager} before it seats any state or by a memo store,
3280
+ * or image files a build has no user turn to carry, carrying the machine-readable `code`
3281
+ * `'SNAPSHOT' | 'IMAGES'`.
3120
3282
  *
3121
3283
  * @remarks
3122
3284
  * A `snapshot` option crosses a foreign boundary (a client, a store, a file), so the manager copies
3123
3285
  * it through JSON and checks the copy: a value JSON cannot carry, a revision missing a field, a
3124
3286
  * non-finite `time`, a sparse `memos` array, a non-string `id`, or a non-array `memos` is a
3125
- * programmer error and throws this with `'SNAPSHOT'`. Narrow a caught value with
3126
- * {@link isContextError} and branch on `error.code`.
3287
+ * programmer error and throws this with `'SNAPSHOT'`, its `context` holding the `faults`. A build
3288
+ * over a conversation that holds turns and no user turn, with image files in the active workspace,
3289
+ * throws `'IMAGES'` rather than dropping them. Narrow a caught value with {@link isContextError} and
3290
+ * branch on `error.code`.
3127
3291
  */
3128
3292
  export declare class ContextError extends Error {
3129
- /** Names the machine-readable condition — `'SNAPSHOT'`: a snapshot option that is not a memo snapshot. */
3293
+ /** Names the machine-readable condition — `'SNAPSHOT'`: a snapshot that is not a memo snapshot; `'IMAGES'`: image files with no user turn to carry them. */
3130
3294
  readonly code: ContextErrorCode;
3131
3295
  /** Holds the values that locate the failure, or `undefined` when none were supplied. */
3132
3296
  readonly context: Readonly<Record<string, unknown>> | undefined;
@@ -3146,7 +3310,7 @@ export declare class ContextError extends Error {
3146
3310
  * @remarks
3147
3311
  * `'SNAPSHOT'`: a `snapshot` option that `isMemoSnapshot` refuses after it is copied through JSON.
3148
3312
  */
3149
- export declare type ContextErrorCode = 'SNAPSHOT';
3313
+ export declare type ContextErrorCode = 'SNAPSHOT' | 'IMAGES';
3150
3314
 
3151
3315
  /**
3152
3316
  * Overrides one context section's format — an `open` / `render` / `close` trio
@@ -3305,12 +3469,12 @@ export declare const CONVERSATION_ROLES: readonly ["user", "assistant", "tool"];
3305
3469
 
3306
3470
  /**
3307
3471
  * Reports a conversation with no {@link ConversationSummaryHandler} to fold its messages with, a
3308
- * `sections` cap below `1`, a `keep` that is not a nonnegative safe integer, a summarizer digest
3472
+ * `sections` cap that is not a positive safe integer, a `keep` that is not a nonnegative safe integer, a summarizer digest
3309
3473
  * whose trimmed text is empty, a judgment or judge request that JSON cannot carry, a stored or
3310
3474
  * selected message whose role is not a conversation role, or a malformed snapshot — thrown by the
3311
3475
  * `compact()` and `add` methods of a {@link ConversationInterface}, its construction, or its
3312
3476
  * judgment store, or returned as the `fault` of an agent selection, carrying the machine-readable
3313
- * `code` `'SUMMARIZER' | 'SECTIONS' | 'JUDGMENT' | 'KEEP' | 'SUMMARY' | 'ROLE' | 'SNAPSHOT'`.
3477
+ * `code` `'SUMMARIZER' | 'SECTIONS' | 'JUDGMENT' | 'KEEP' | 'SUMMARY' | 'ROLE' | 'MESSAGE' | 'SNAPSHOT' | 'ID'`.
3314
3478
  *
3315
3479
  * @remarks
3316
3480
  * Compaction requires a summarizer (it digests the folded slice into a section summary); a
@@ -3318,7 +3482,7 @@ export declare const CONVERSATION_ROLES: readonly ["user", "assistant", "tool"];
3318
3482
  * is a programmer error and throws this with `'SUMMARIZER'`.
3319
3483
  * A `sections` cap (on {@link import('./types.js').ConversationOptions} /
3320
3484
  * {@link import('./types.js').ConversationManagerOptions} /
3321
- * {@link import('./types.js').CompactOptions}) must be `>= 1`, and cannot combine with
3485
+ * {@link import('./types.js').CompactOptions}) must be a positive safe integer, and cannot combine with
3322
3486
  * `cumulative` — either is a programmer error and throws this with `'SECTIONS'`. A `keep` on the same options must be a nonnegative
3323
3487
  * safe integer — any other value is a programmer error and throws this with `'KEEP'`. A judgment
3324
3488
  * record or a judge request that JSON cannot carry, or whose copy fails its guard, is a
@@ -3326,13 +3490,16 @@ export declare const CONVERSATION_ROLES: readonly ["user", "assistant", "tool"];
3326
3490
  * where one exists. A summarizer digest whose trimmed text is empty rejects the `compact()` with
3327
3491
  * `'SUMMARY'`. A stored message plays a `ConversationRole`: `add` refuses any other role with
3328
3492
  * `'ROLE'` before it stores any message of the batch, a hydrating snapshot that holds one throws
3329
- * `'ROLE'`, and an agent's selection that holds one becomes a `'ROLE'` fault. A hydrating snapshot
3330
- * that fails `isConversationSnapshot` or repeats an id throws `'SNAPSHOT'`; a judgment the guard
3331
- * admits but JSON cannot carry still throws `'JUDGMENT'`. Narrow a caught value with
3493
+ * `'ROLE'`, and an agent's selection that holds one becomes a `'ROLE'` fault. `add` refuses an input
3494
+ * whose other members fail `isMessageInput` with `'MESSAGE'`, its `context` holding the `faults`,
3495
+ * before it stores any message of the batch. A hydrating snapshot that fails
3496
+ * `isConversationSnapshot` or repeats an id, and a store row or written snapshot that does, throw
3497
+ * `'SNAPSHOT'`; a judgment the guard admits but JSON cannot carry still throws `'JUDGMENT'`. A
3498
+ * manager's `add` of an id it already holds throws `'ID'`. Narrow a caught value with
3332
3499
  * {@link isConversationError} and branch on `error.code`.
3333
3500
  */
3334
3501
  export declare class ConversationError extends Error {
3335
- /** Names the machine-readable condition — `'SUMMARIZER'`: a `compact()` with no summarizer; `'SECTIONS'`: a sub-1 `sections` cap, or a cap combined with `cumulative`; `'JUDGMENT'`: a judgment or judge request that is not JSON; `'KEEP'`: a `keep` that is not a nonnegative safe integer; `'SUMMARY'`: a summarizer digest whose trimmed text is empty; `'ROLE'`: a stored or selected message whose role is not a `ConversationRole`; `'SNAPSHOT'`: a snapshot that fails `isConversationSnapshot` or repeats an id. */
3502
+ /** Names the machine-readable condition — `'SUMMARIZER'`: a `compact()` with no summarizer; `'SECTIONS'`: a `sections` cap that is not a positive safe integer, or a cap combined with `cumulative`; `'JUDGMENT'`: a judgment or judge request that is not JSON; `'KEEP'`: a `keep` that is not a nonnegative safe integer; `'SUMMARY'`: a summarizer digest whose trimmed text is empty; `'ROLE'`: a stored or selected message whose role is not a `ConversationRole`; `'MESSAGE'`: a message input whose other members fail `isMessageInput`; `'SNAPSHOT'`: a snapshot that fails `isConversationSnapshot` or repeats an id; `'ID'`: a manager's `add` of an id it already holds. */
3336
3503
  readonly code: ConversationErrorCode;
3337
3504
  /** Holds the values that locate the failure, such as the `question` id of a malformed question, or `undefined` when none were supplied. */
3338
3505
  readonly context: Readonly<Record<string, unknown>> | undefined;
@@ -3359,7 +3526,7 @@ export declare class ConversationError extends Error {
3359
3526
  * `'SNAPSHOT'`: a snapshot that fails `isConversationSnapshot` or repeats an id; a judgment the
3360
3527
  * guard admits but JSON cannot carry still raises `'JUDGMENT'`.
3361
3528
  */
3362
- export declare type ConversationErrorCode = 'SUMMARIZER' | 'SECTIONS' | 'JUDGMENT' | 'KEEP' | 'SUMMARY' | 'ROLE' | 'SNAPSHOT';
3529
+ export declare type ConversationErrorCode = 'SUMMARIZER' | 'SECTIONS' | 'JUDGMENT' | 'KEEP' | 'SUMMARY' | 'ROLE' | 'MESSAGE' | 'SNAPSHOT' | 'ID';
3363
3530
 
3364
3531
  /**
3365
3532
  * Maps the push observation surface of a {@link ConversationInterface} — the compaction
@@ -3678,7 +3845,8 @@ export declare interface ConversationInterface {
3678
3845
  * - **Registry.** Conversations live in an insertion-ordered `Map` keyed by `id`. `add(input?)`
3679
3846
  * mints a {@link Conversation} (its `id` from `input` or `crypto.randomUUID()`), flowing the
3680
3847
  * default `#summarize` / `#keep` of the manager in unless the `input` overrides them, and stores
3681
- * it (an already-present `id` overwrites — last write wins). `count` is the map size,
3848
+ * it (an already-present `id` throws a `ConversationError` coded `'ID'`, because replacing a live
3849
+ * conversation would orphan its turns). `count` is the map size,
3682
3850
  * `conversation(id)` looks one up, `conversations()` lists them in insertion order.
3683
3851
  * - **Active pointer.** `active` is the active conversation (the conversation an agent run binds
3684
3852
  * when it names none), `undefined` until the first `add` (which auto-activates it — a registry
@@ -3728,7 +3896,7 @@ export declare class ConversationManager implements ConversationManagerInterface
3728
3896
  * - **Registry.** `count` is how many are stored. `add(input?)` mints a
3729
3897
  * {@link ConversationInterface} (its `id` from `input` or a random UUID), flowing the
3730
3898
  * default `summarize` / `keep` of the manager in unless the `input` overrides them; `add` of an
3731
- * already-present `id` overwrites it (last write wins). `conversation(id)` looks one up
3899
+ * already-present `id` throws (code `'ID'`). `conversation(id)` looks one up
3732
3900
  * (`undefined` when absent); `conversations()` lists them in insertion order.
3733
3901
  * - **Active pointer.** `active` is the active conversation (the conversation an agent run binds
3734
3902
  * when it names none, and the one the context renders with no selection), `undefined` until the
@@ -3770,11 +3938,11 @@ export declare interface ConversationManagerInterface {
3770
3938
  /**
3771
3939
  * Mints a conversation, taking its `id` from the input or a fresh UUID and flowing the
3772
3940
  * default `summarize` / `keep` of the manager in unless the input overrides them —
3773
- * auto-activates the first, and an already-present `id` overwrites, last write wins.
3941
+ * auto-activates the first, and an already-present `id` throws.
3774
3942
  *
3775
3943
  * @param input - Optional {@link ConversationInput} overrides
3776
3944
  * @returns The created conversation
3777
- * @throws ConversationError Thrown when `snapshot` is malformed or repeats an id (code `'SNAPSHOT'`) or holds a message whose role is not a `ConversationRole` (code `'ROLE'`); nothing registers and `active` is unchanged
3945
+ * @throws ConversationError Thrown when the `id` is already live (code `'ID'`), or when `snapshot` is malformed or repeats an id (code `'SNAPSHOT'`) or holds a message whose role is not a `ConversationRole` (code `'ROLE'`); nothing registers and `active` is unchanged
3778
3946
  */
3779
3947
  add(input?: ConversationInput): ConversationInterface;
3780
3948
  /**
@@ -3977,8 +4145,8 @@ export declare type ConversationRole = (typeof CONVERSATION_ROLES)[number];
3977
4145
  * {@link ConversationManagerInterface} hydrates a conversation from it through that seam (see
3978
4146
  * {@link ConversationManagerInterface.open}). It is narrowed back from an untrusted storage read by
3979
4147
  * {@link import('./validators.js').isConversationSnapshot} (the total boundary guard), which
3980
- * admits unknown members: a 0.0.29 snapshot that carries a conversation `summary` passes and
3981
- * hydrates without it.
4148
+ * is exact: an unknown member refuses, so a 0.0.29 snapshot that carries a conversation `summary`
4149
+ * throws until its row is rewritten without the key.
3982
4150
  */
3983
4151
  export declare interface ConversationSnapshot {
3984
4152
  readonly id: string;
@@ -3990,6 +4158,158 @@ export declare interface ConversationSnapshot {
3990
4158
  readonly messages: readonly Message[];
3991
4159
  }
3992
4160
 
4161
+ /** Reads the faults of a refused conversation snapshot. */
4162
+ export declare const conversationSnapshotContract: ContractInterface<Readonly<{
4163
+ id: string;
4164
+ sections: readonly Readonly<{
4165
+ id: string;
4166
+ summary: string;
4167
+ messages: readonly Readonly<{
4168
+ id: string;
4169
+ role: "assistant" | "system" | "tool" | "user";
4170
+ content: string;
4171
+ } & {
4172
+ calls?: readonly Readonly<{
4173
+ id: string;
4174
+ name: string;
4175
+ arguments: {
4176
+ readonly [k: string]: JSONValue;
4177
+ };
4178
+ } & {}>[];
4179
+ call?: string;
4180
+ images?: readonly string[];
4181
+ thinking?: string;
4182
+ }>[];
4183
+ } & {}>[];
4184
+ messages: readonly Readonly<{
4185
+ id: string;
4186
+ role: "assistant" | "system" | "tool" | "user";
4187
+ content: string;
4188
+ } & {
4189
+ calls?: readonly Readonly<{
4190
+ id: string;
4191
+ name: string;
4192
+ arguments: {
4193
+ readonly [k: string]: JSONValue;
4194
+ };
4195
+ } & {}>[];
4196
+ call?: string;
4197
+ images?: readonly string[];
4198
+ thinking?: string;
4199
+ }>[];
4200
+ } & {
4201
+ judgments?: readonly (Readonly<{
4202
+ id: string;
4203
+ question: Readonly<{
4204
+ form: "choice";
4205
+ criteria: {
4206
+ readonly [k: string]: string | readonly JSONValue[] | {
4207
+ readonly [k: string]: JSONValue;
4208
+ } | null;
4209
+ };
4210
+ } & {
4211
+ instructions?: string | readonly JSONValue[] | {
4212
+ readonly [k: string]: JSONValue;
4213
+ };
4214
+ }> | Readonly<{
4215
+ form: "score";
4216
+ criteria: readonly (string | readonly JSONValue[] | {
4217
+ readonly [k: string]: JSONValue;
4218
+ } | null)[];
4219
+ } & {
4220
+ instructions?: string | readonly JSONValue[] | {
4221
+ readonly [k: string]: JSONValue;
4222
+ };
4223
+ }> | Readonly<{
4224
+ form: "noul";
4225
+ } & {
4226
+ instructions?: string | readonly JSONValue[] | {
4227
+ readonly [k: string]: JSONValue;
4228
+ };
4229
+ criteria?: Readonly<{} & {
4230
+ true?: string | readonly JSONValue[] | {
4231
+ readonly [k: string]: JSONValue;
4232
+ };
4233
+ false?: string | readonly JSONValue[] | {
4234
+ readonly [k: string]: JSONValue;
4235
+ };
4236
+ }>;
4237
+ }>;
4238
+ model: string;
4239
+ sources: readonly string[];
4240
+ state: string;
4241
+ time: number;
4242
+ answer: Readonly<{
4243
+ form: "choice";
4244
+ probabilities: {
4245
+ readonly [k: string]: number;
4246
+ };
4247
+ } & {}> | Readonly<{
4248
+ form: "score";
4249
+ probabilities: readonly number[];
4250
+ } & {}> | Readonly<{
4251
+ form: "noul";
4252
+ noul: number;
4253
+ } & {}>;
4254
+ } & {
4255
+ usage?: Readonly<{
4256
+ prompt: number;
4257
+ completion: number;
4258
+ total: number;
4259
+ } & {}>;
4260
+ }> | Readonly<{
4261
+ id: string;
4262
+ question: Readonly<{
4263
+ form: "choice";
4264
+ criteria: {
4265
+ readonly [k: string]: string | readonly JSONValue[] | {
4266
+ readonly [k: string]: JSONValue;
4267
+ } | null;
4268
+ };
4269
+ } & {
4270
+ instructions?: string | readonly JSONValue[] | {
4271
+ readonly [k: string]: JSONValue;
4272
+ };
4273
+ }> | Readonly<{
4274
+ form: "score";
4275
+ criteria: readonly (string | readonly JSONValue[] | {
4276
+ readonly [k: string]: JSONValue;
4277
+ } | null)[];
4278
+ } & {
4279
+ instructions?: string | readonly JSONValue[] | {
4280
+ readonly [k: string]: JSONValue;
4281
+ };
4282
+ }> | Readonly<{
4283
+ form: "noul";
4284
+ } & {
4285
+ instructions?: string | readonly JSONValue[] | {
4286
+ readonly [k: string]: JSONValue;
4287
+ };
4288
+ criteria?: Readonly<{} & {
4289
+ true?: string | readonly JSONValue[] | {
4290
+ readonly [k: string]: JSONValue;
4291
+ };
4292
+ false?: string | readonly JSONValue[] | {
4293
+ readonly [k: string]: JSONValue;
4294
+ };
4295
+ }>;
4296
+ }>;
4297
+ model: string;
4298
+ sources: readonly string[];
4299
+ state: string;
4300
+ time: number;
4301
+ refusal: Readonly<{
4302
+ missing: readonly string[];
4303
+ } & {}>;
4304
+ } & {
4305
+ usage?: Readonly<{
4306
+ prompt: number;
4307
+ completion: number;
4308
+ total: number;
4309
+ } & {}>;
4310
+ }>)[];
4311
+ }>>;
4312
+
3993
4313
  /**
3994
4314
  * Represents one row of the table a {@link
3995
4315
  * import('./stores/DatabaseConversationStore.js').DatabaseConversationStore} persists
@@ -4014,6 +4334,116 @@ export declare interface ConversationSnapshotRow {
4014
4334
  readonly snapshot: unknown;
4015
4335
  }
4016
4336
 
4337
+ /**
4338
+ * Describes a conversation snapshot exactly: an unknown key refuses, so a key a later version adds never
4339
+ * reads as absent.
4340
+ *
4341
+ * @remarks
4342
+ * `isConversationSnapshot` is the door a hydrate and a store read, and this shape fills a refusal's
4343
+ * faults. A lockstep test holds that `is` implies the guard, and on the snapshot fixtures the converse.
4344
+ */
4345
+ export declare const conversationSnapshotShape: ObjectShape< {
4346
+ id: StringShape;
4347
+ sections: ArrayShape<ObjectShape< {
4348
+ id: StringShape;
4349
+ summary: StringShape;
4350
+ messages: ArrayShape<ObjectShape< {
4351
+ id: StringShape;
4352
+ role: LiteralShape<readonly ["system", "user", "assistant", "tool"]>;
4353
+ content: StringShape;
4354
+ calls: OptionalShape<ArrayShape<ObjectShape< {
4355
+ id: StringShape;
4356
+ name: StringShape;
4357
+ arguments: ObjectShape<Record<never, never>, JSONShape>;
4358
+ }, boolean | ContractShape>>>;
4359
+ call: OptionalShape<StringShape>;
4360
+ images: OptionalShape<ArrayShape<StringShape>>;
4361
+ thinking: OptionalShape<StringShape>;
4362
+ }, boolean | ContractShape>>;
4363
+ }, boolean | ContractShape>>;
4364
+ messages: ArrayShape<ObjectShape< {
4365
+ id: StringShape;
4366
+ role: LiteralShape<readonly ["system", "user", "assistant", "tool"]>;
4367
+ content: StringShape;
4368
+ calls: OptionalShape<ArrayShape<ObjectShape< {
4369
+ id: StringShape;
4370
+ name: StringShape;
4371
+ arguments: ObjectShape<Record<never, never>, JSONShape>;
4372
+ }, boolean | ContractShape>>>;
4373
+ call: OptionalShape<StringShape>;
4374
+ images: OptionalShape<ArrayShape<StringShape>>;
4375
+ thinking: OptionalShape<StringShape>;
4376
+ }, boolean | ContractShape>>;
4377
+ judgments: OptionalShape<ArrayShape<UnionShape<readonly [ObjectShape< {
4378
+ id: StringShape;
4379
+ question: UnionShape<readonly [ObjectShape< {
4380
+ form: LiteralShape<readonly ["choice"]>;
4381
+ instructions: OptionalShape<UnionShape<readonly [StringShape, ArrayShape<JSONShape>, ObjectShape<Record<never, never>, JSONShape>]>>;
4382
+ criteria: ObjectShape<Record<never, never>, NullableShape<UnionShape<readonly [StringShape, ArrayShape<JSONShape>, ObjectShape<Record<never, never>, JSONShape>]>>>;
4383
+ }, boolean | ContractShape>, ObjectShape< {
4384
+ form: LiteralShape<readonly ["score"]>;
4385
+ instructions: OptionalShape<UnionShape<readonly [StringShape, ArrayShape<JSONShape>, ObjectShape<Record<never, never>, JSONShape>]>>;
4386
+ criteria: ArrayShape<NullableShape<UnionShape<readonly [StringShape, ArrayShape<JSONShape>, ObjectShape<Record<never, never>, JSONShape>]>>>;
4387
+ }, boolean | ContractShape>, ObjectShape< {
4388
+ form: LiteralShape<readonly ["noul"]>;
4389
+ instructions: OptionalShape<UnionShape<readonly [StringShape, ArrayShape<JSONShape>, ObjectShape<Record<never, never>, JSONShape>]>>;
4390
+ criteria: OptionalShape<ObjectShape< {
4391
+ true: OptionalShape<UnionShape<readonly [StringShape, ArrayShape<JSONShape>, ObjectShape<Record<never, never>, JSONShape>]>>;
4392
+ false: OptionalShape<UnionShape<readonly [StringShape, ArrayShape<JSONShape>, ObjectShape<Record<never, never>, JSONShape>]>>;
4393
+ }, boolean | ContractShape>>;
4394
+ }, boolean | ContractShape>]>;
4395
+ model: StringShape;
4396
+ sources: ArrayShape<StringShape>;
4397
+ state: StringShape;
4398
+ time: NumberShape;
4399
+ usage: OptionalShape<ObjectShape< {
4400
+ prompt: NumberShape;
4401
+ completion: NumberShape;
4402
+ total: NumberShape;
4403
+ }, boolean | ContractShape>>;
4404
+ answer: UnionShape<readonly [ObjectShape< {
4405
+ form: LiteralShape<readonly ["choice"]>;
4406
+ probabilities: ObjectShape<Record<never, never>, NumberShape>;
4407
+ }, boolean | ContractShape>, ObjectShape< {
4408
+ form: LiteralShape<readonly ["score"]>;
4409
+ probabilities: ArrayShape<NumberShape>;
4410
+ }, boolean | ContractShape>, ObjectShape< {
4411
+ form: LiteralShape<readonly ["noul"]>;
4412
+ noul: NumberShape;
4413
+ }, boolean | ContractShape>]>;
4414
+ }, boolean | ContractShape>, ObjectShape< {
4415
+ id: StringShape;
4416
+ question: UnionShape<readonly [ObjectShape< {
4417
+ form: LiteralShape<readonly ["choice"]>;
4418
+ instructions: OptionalShape<UnionShape<readonly [StringShape, ArrayShape<JSONShape>, ObjectShape<Record<never, never>, JSONShape>]>>;
4419
+ criteria: ObjectShape<Record<never, never>, NullableShape<UnionShape<readonly [StringShape, ArrayShape<JSONShape>, ObjectShape<Record<never, never>, JSONShape>]>>>;
4420
+ }, boolean | ContractShape>, ObjectShape< {
4421
+ form: LiteralShape<readonly ["score"]>;
4422
+ instructions: OptionalShape<UnionShape<readonly [StringShape, ArrayShape<JSONShape>, ObjectShape<Record<never, never>, JSONShape>]>>;
4423
+ criteria: ArrayShape<NullableShape<UnionShape<readonly [StringShape, ArrayShape<JSONShape>, ObjectShape<Record<never, never>, JSONShape>]>>>;
4424
+ }, boolean | ContractShape>, ObjectShape< {
4425
+ form: LiteralShape<readonly ["noul"]>;
4426
+ instructions: OptionalShape<UnionShape<readonly [StringShape, ArrayShape<JSONShape>, ObjectShape<Record<never, never>, JSONShape>]>>;
4427
+ criteria: OptionalShape<ObjectShape< {
4428
+ true: OptionalShape<UnionShape<readonly [StringShape, ArrayShape<JSONShape>, ObjectShape<Record<never, never>, JSONShape>]>>;
4429
+ false: OptionalShape<UnionShape<readonly [StringShape, ArrayShape<JSONShape>, ObjectShape<Record<never, never>, JSONShape>]>>;
4430
+ }, boolean | ContractShape>>;
4431
+ }, boolean | ContractShape>]>;
4432
+ model: StringShape;
4433
+ sources: ArrayShape<StringShape>;
4434
+ state: StringShape;
4435
+ time: NumberShape;
4436
+ usage: OptionalShape<ObjectShape< {
4437
+ prompt: NumberShape;
4438
+ completion: NumberShape;
4439
+ total: NumberShape;
4440
+ }, boolean | ContractShape>>;
4441
+ refusal: ObjectShape< {
4442
+ missing: ArrayShape<StringShape>;
4443
+ }, boolean | ContractShape>;
4444
+ }, boolean | ContractShape>]>>>;
4445
+ }, boolean | ContractShape>;
4446
+
4017
4447
  /**
4018
4448
  * Persists a {@link ConversationSnapshot} durably — the async `get` / `set` / `delete` primitives,
4019
4449
  * keyed by a conversation id and holding no expiry, the exact analogue of {@link
@@ -4251,16 +4681,29 @@ export declare function createAgentQueue(options: AgentQueueOptions): QueueInter
4251
4681
  *
4252
4682
  * @example
4253
4683
  * ```ts
4254
- * import { createAgentRegistry } from '@orkestrel/agent'
4684
+ * import { createAgentRegistry, createAuthority } from '@orkestrel/agent'
4255
4685
  * import type { ProviderInterface } from '@orkestrel/agent'
4686
+ * import { numberShape, objectShape } from '@orkestrel/contract'
4256
4687
  * import { createTool } from '@orkestrel/tool'
4257
4688
  *
4258
4689
  * declare const provider: ProviderInterface // any concrete implementation supplied by the host app
4259
4690
  * const registry = createAgentRegistry({
4260
4691
  * providers: { main: provider },
4261
- * tools: { add: createTool({ name: 'add', execute: (a) => Number(a.x) + Number(a.y) }) },
4692
+ * tools: {
4693
+ * add: createTool({
4694
+ * name: 'add',
4695
+ * contract: objectShape({ x: numberShape(), y: numberShape() }),
4696
+ * execute: (a) => Number(a.x) + Number(a.y),
4697
+ * }),
4698
+ * },
4699
+ * authorities: { open: createAuthority({ fallback: { zone: 'default', verdict: 'allow' } }) },
4700
+ * })
4701
+ * const agent = registry.build({
4702
+ * provider: 'main',
4703
+ * messages: [{ role: 'user', content: 'Hi.' }],
4704
+ * tools: ['add'],
4705
+ * authority: 'open',
4262
4706
  * })
4263
- * const agent = registry.build({ provider: 'main', messages: [{ role: 'user', content: 'Hi.' }] })
4264
4707
  * ```
4265
4708
  */
4266
4709
  export declare function createAgentRegistry(options: AgentRegistryOptions): AgentRegistryInterface;
@@ -4319,7 +4762,11 @@ export declare function createAgentRunner(options: AgentRunnerOptions): RunnerIn
4319
4762
  * @example
4320
4763
  * ```ts
4321
4764
  * const approver = createApprover()
4322
- * const authority = createAuthority({ rules, ask: approver.ask })
4765
+ * const authority = createAuthority({
4766
+ * rules,
4767
+ * fallback: { zone: 'default', verdict: 'deny' },
4768
+ * ask: approver.ask,
4769
+ * })
4323
4770
  * const agent = createAgent(provider, { tools, authority })
4324
4771
  * const stream = agent.stream({ prompt: { content: 'Tidy the notes.' } })
4325
4772
  * for await (const frame of agentStreamToFrames(stream, approver)) {
@@ -4332,20 +4779,20 @@ export declare function createApprover(): ApproverInterface;
4332
4779
  /**
4333
4780
  * Creates a policy gate — an {@link AuthorityInterface} the agent loop consults before
4334
4781
  * each tool call runs, evaluating the ordered rules first-match-wins and falling back
4335
- * to the configured default when none match.
4782
+ * to the required `fallback` when none match.
4336
4783
  *
4337
4784
  * @remarks
4338
- * `rules` are evaluated in order — the first whose `match` is true decides (a matched
4339
- * rule with no `verdict` allows). When no rule matches, the `fallback` decides. Default:
4340
- * `{ zone: DEFAULT_AUTHORITY_ZONE, verdict: 'allow' }` (allow-unmatched — a rules list of
4341
- * denials acts as a denylist). Pass a `verdict: 'deny'` `fallback` to flip the gate to
4342
- * deny-by-default (an allowlist). `ask` answers each `ask` verdict; with none, every ask is
4343
- * refused as unanswered. Wire the result into `createAgent` through `AgentOptions.authority`:
4344
- * a denied call is fed back to the model as a denial `ToolResult` (not executed), so the model
4345
- * can react. Synchronous — `evaluate` returns the verdict directly; only `ask` is async.
4785
+ * `rules` are evaluated in order — the first whose `match` is true decides, and each rule names its
4786
+ * `verdict`. When no rule matches, the `fallback` decides: a `verdict: 'deny'` fallback makes an
4787
+ * allowlist, and a `verdict: 'allow'` fallback makes a denylist. `ask` answers each `ask` verdict;
4788
+ * with none, every ask is refused as unanswered. Wire the result into `createAgent` through
4789
+ * `AgentOptions.authority`: a denied call is fed back to the model as a denial `ToolResult` (not
4790
+ * executed), so the model can react. Synchronous — `evaluate` returns the verdict directly; only
4791
+ * `ask` is async.
4346
4792
  *
4347
- * @param options - Optional `rules` (ordered), `fallback`, and `ask` (see {@link AuthorityOptions})
4793
+ * @param options - The `fallback`, and optional `rules` (ordered) and `ask` (see {@link AuthorityOptions})
4348
4794
  * @returns A working {@link AuthorityInterface}
4795
+ * @throws {AgentError} Thrown when the `fallback` is missing or malformed, or a rule has no valid `verdict` (code `'AUTHORITY'`)
4349
4796
  *
4350
4797
  * @example
4351
4798
  * ```ts
@@ -4354,11 +4801,12 @@ export declare function createApprover(): ApproverInterface;
4354
4801
  * // Deny the `delete` tool, allow everything else.
4355
4802
  * const authority = createAuthority({
4356
4803
  * rules: [{ match: (c) => c.call.name === 'delete', zone: 'restricted', verdict: 'deny' }],
4804
+ * fallback: { zone: 'default', verdict: 'allow' },
4357
4805
  * })
4358
4806
  * const agent = createAgent(provider, { tools, authority })
4359
4807
  * ```
4360
4808
  */
4361
- export declare function createAuthority(options?: AuthorityOptions): AuthorityInterface;
4809
+ export declare function createAuthority(options: AuthorityOptions): AuthorityInterface;
4362
4810
 
4363
4811
  /**
4364
4812
  * Creates an empty unbounded async channel — a {@link ChannelInterface} a producer writes
@@ -4456,7 +4904,7 @@ export declare function createConversation(options?: ConversationOptions): Conve
4456
4904
  * @remarks
4457
4905
  * Starts empty; `add(input?)` mints a {@link ConversationInterface} (its `id` from the input
4458
4906
  * or a random UUID), flowing the manager's default `summarize` / `keep` in unless the input
4459
- * overrides them, and stores it (an already-present `id` overwrites — last write wins) — and
4907
+ * overrides them, and stores it (an already-present `id` throws, code `'ID'`) — and
4460
4908
  * auto-activates the first one (a registry with conversations always has one `active`); a later
4461
4909
  * `add` leaves `active` unchanged. `switch(id)` re-points `active` (an unknown `id` returns
4462
4910
  * `undefined`, leaving `active` unchanged — lenient, never throws); `conversation(id)` /
@@ -4903,10 +5351,12 @@ export declare function createThinkSplitter(): ThinkSplitterInterface;
4903
5351
  * @remarks
4904
5352
  * The cut keeps at least one entry. When it leaves entries out, its last line reads
4905
5353
  * `N older items not shown; name a narrower topic to narrow the recall`, which
4906
- * {@link matchesCutLine} recognizes.
5354
+ * {@link matchesCutLine} recognizes. Pass `more` when the entries aren't in age order, so the line
5355
+ * doesn't claim an omitted entry is older than a kept one.
4907
5356
  *
4908
5357
  * @param entries - The entries in the order they are kept
4909
5358
  * @param room - The estimate units the joined entries can take
5359
+ * @param kind - What the cut line calls an omitted entry. Default: `older`
4910
5360
  * @returns The kept entries followed by the cut line when any were left out, joined by newlines
4911
5361
  *
4912
5362
  * @example
@@ -4914,7 +5364,7 @@ export declare function createThinkSplitter(): ThinkSplitterInterface;
4914
5364
  * cutListing(['first entry', 'second entry'], 1) // 'first entry\n1 older item not shown; name a narrower topic to narrow the recall'
4915
5365
  * ```
4916
5366
  */
4917
- export declare function cutListing(entries: readonly string[], room: number): string;
5367
+ export declare function cutListing(entries: readonly string[], room: number, kind?: 'older' | 'more'): string;
4918
5368
 
4919
5369
  /**
4920
5370
  * Backs a {@link ConversationStoreInterface} with one table of the `databases` layer — a
@@ -4946,8 +5396,9 @@ export declare function cutListing(entries: readonly string[], room: number): st
4946
5396
  * the row `{ id: snapshot.id, snapshot }`.
4947
5397
  * - **`get(id)` resolves the stored snapshot for an id**, narrowing the opaque JSON column back to
4948
5398
  * a {@link ConversationSnapshot} ({@link import('../validators.js').isConversationSnapshot} — the
4949
- * total guard for an untrusted storage read), or `undefined` if none is stored, the blob is
4950
- * malformed, or the blob's own `id` is not the requested one.
5399
+ * total guard for an untrusted storage read), or `undefined` only when no row is stored. A row whose
5400
+ * blob is malformed or names another id throws a `ConversationError` coded `'SNAPSHOT'`, so `open`
5401
+ * and `create` stop rather than overwrite it, and `delete` still removes it.
4951
5402
  * - **`delete(id)` drops a snapshot by id**; an absent id is a no-op (no throw).
4952
5403
  *
4953
5404
  * Unlike a session store there is no idle-TTL / eviction — a persisted conversation lives until an
@@ -4984,12 +5435,12 @@ export declare class DatabaseConversationStore implements ConversationStoreInter
4984
5435
  *
4985
5436
  * @remarks
4986
5437
  * The column is an untrusted storage read, so a blob that fails
4987
- * {@link import('../validators.js').isConversationSnapshot}, or whose own `id` is not `id`,
4988
- * resolves `undefined` rather than a conversation under the wrong key.
5438
+ * {@link import('../validators.js').isConversationSnapshot}, or whose own `id` is not `id`, throws
5439
+ * rather than reading as absent, which would let a later `set` overwrite it.
4989
5440
  *
4990
5441
  * @param id - The conversation id to resolve (the row key)
4991
- * @returns The persisted snapshot, or `undefined` when no row is stored, the blob is malformed,
4992
- * or the blob names another id
5442
+ * @returns The persisted snapshot, or `undefined` when no row is stored
5443
+ * @throws {ConversationError} Thrown when the row's blob is malformed or names another id (code `'SNAPSHOT'`), with the faults under `context.faults`
4993
5444
  */
4994
5445
  get(id: string): Promise<ConversationSnapshot | undefined>;
4995
5446
  /**
@@ -4998,6 +5449,7 @@ export declare class DatabaseConversationStore implements ConversationStoreInter
4998
5449
  *
4999
5450
  * @param snapshot - The snapshot to store, keyed by its `id`
5000
5451
  * @returns A promise that resolves after the row is written
5452
+ * @throws {ConversationError} Thrown before any write when the snapshot fails the guard `get` reads (code `'SNAPSHOT'`), so no row is written that `get` refuses
5001
5453
  */
5002
5454
  set(snapshot: ConversationSnapshot): Promise<void>;
5003
5455
  /**
@@ -5031,8 +5483,9 @@ export declare class DatabaseConversationStore implements ConversationStoreInter
5031
5483
  * the row `{ id: snapshot.id, snapshot }`.
5032
5484
  * - **`get(id)` resolves the stored snapshot for an id**, narrowing the opaque JSON column back to
5033
5485
  * a {@link MemoSnapshot} ({@link import('../validators.js').isMemoSnapshot} — the total guard for
5034
- * an untrusted storage read), or `undefined` if none is stored, the blob is malformed, or the
5035
- * blob's own `id` is not the requested one.
5486
+ * an untrusted storage read), or `undefined` only when no row is stored. A row whose blob is malformed
5487
+ * or names another id throws a `ContextError` coded `'SNAPSHOT'`, so a host never overwrites it
5488
+ * unawares, and `delete` still removes it.
5036
5489
  * - **`delete(id)` drops a snapshot by id**; an absent id is a no-op (no throw).
5037
5490
  *
5038
5491
  * @example
@@ -5063,12 +5516,12 @@ export declare class DatabaseMemoStore implements MemoStoreInterface {
5063
5516
  *
5064
5517
  * @remarks
5065
5518
  * The column is an untrusted storage read, so a blob that fails
5066
- * {@link import('../validators.js').isMemoSnapshot}, or whose own `id` is not `id`, resolves
5067
- * `undefined` rather than a memo set under the wrong key.
5519
+ * {@link import('../validators.js').isMemoSnapshot}, or whose own `id` is not `id`, throws rather
5520
+ * than reading as absent.
5068
5521
  *
5069
5522
  * @param id - The memo set id to resolve (the row key)
5070
- * @returns The stored snapshot, or `undefined` when no row is stored, the blob is malformed, or
5071
- * the blob names another id
5523
+ * @returns The stored snapshot, or `undefined` when no row is stored
5524
+ * @throws {ContextError} Thrown when the row's blob is malformed or names another id (code `'SNAPSHOT'`), with the faults under `context.faults`
5072
5525
  */
5073
5526
  get(id: string): Promise<MemoSnapshot | undefined>;
5074
5527
  /**
@@ -5077,6 +5530,7 @@ export declare class DatabaseMemoStore implements MemoStoreInterface {
5077
5530
  *
5078
5531
  * @param snapshot - The snapshot to store, keyed by its `id`
5079
5532
  * @returns A promise that resolves after the row is written
5533
+ * @throws {ContextError} Thrown before any write when the snapshot fails the guard `get` reads (code `'SNAPSHOT'`), so no row is written that `get` refuses
5080
5534
  */
5081
5535
  set(snapshot: MemoSnapshot): Promise<void>;
5082
5536
  /**
@@ -5098,11 +5552,6 @@ export declare const DECISIVE_CATEGORIES: readonly LedgerCategory[];
5098
5552
  */
5099
5553
  export declare const DEFAULT_AGENT_LIMIT = 10;
5100
5554
 
5101
- /**
5102
- * Names the default zone for an unmatched tool call allowed by an authority.
5103
- */
5104
- export declare const DEFAULT_AUTHORITY_ZONE = "default";
5105
-
5106
5555
  /**
5107
5556
  * Sets the default number of recent live messages the `compact()` method of a
5108
5557
  * {@link ConversationInterface} retains verbatim — `0`, so a manual `compact()` keeps no recent tail and folds every
@@ -5165,6 +5614,25 @@ export declare const DEFAULT_RELAY_LIMIT = 1048576;
5165
5614
  */
5166
5615
  export declare function denyCall(call: ToolCall, reason: string | undefined): ToolResult;
5167
5616
 
5617
+ /**
5618
+ * Describes why a judge question refuses, in the text both of its doors throw.
5619
+ *
5620
+ * @remarks
5621
+ * The rule travels in the text because the question shape cannot state it: a record has no minimum
5622
+ * size, so a single-option choice refuses at the guard with no fault for the list to name.
5623
+ *
5624
+ * @param id - The question's id
5625
+ * @param faults - What the question shape's audit found
5626
+ * @param schema - The question shape's JSON Schema
5627
+ * @returns The refusal text, with the fault list on the lines after it
5628
+ * @example
5629
+ * ```ts
5630
+ * describeQuestionRefusal('team', [], judgeQuestionContract.schema)
5631
+ * // 'question team is malformed; a choice names two or more criteria, a score two or more levels, and a noul only true and false'
5632
+ * ```
5633
+ */
5634
+ export declare function describeQuestionRefusal(id: string, faults: readonly AuditFault[], schema: JSONSchema): string;
5635
+
5168
5636
  /**
5169
5637
  * Describes one relay refusal as the line its `422` response body carries.
5170
5638
  *
@@ -5186,11 +5654,44 @@ export declare function denyCall(call: ToolCall, reason: string | undefined): To
5186
5654
  */
5187
5655
  export declare function describeRelayRefusal(refusal: RelayRefusal): string;
5188
5656
 
5657
+ /**
5658
+ * Describes a snapshot a store refuses, naming its id, the first fault, and what a host does about it.
5659
+ *
5660
+ * @remarks
5661
+ * A store's row is the host's table, so the text tells the host to read the row itself and rewrite it,
5662
+ * or to delete it, rather than reading a refused row as absent, which would let `open` overwrite it.
5663
+ * The id and each fault segment are JSON-encoded and length-capped.
5664
+ *
5665
+ * @param noun - What the snapshot holds, such as `conversation`
5666
+ * @param id - The id the row is keyed by
5667
+ * @param faults - The faults of the snapshot's shape
5668
+ * @returns The refusal's text
5669
+ * @example
5670
+ * ```ts
5671
+ * describeSnapshotRefusal('conversation', 'c1', [{ reason: 'extra', path: ['summary'] }])
5672
+ * // 'conversation "c1" holds a snapshot this version refuses (extra key "summary" at the root; ...'
5673
+ * ```
5674
+ */
5675
+ export declare function describeSnapshotRefusal(noun: string, id: unknown, faults: readonly AuditFault[]): string;
5676
+
5189
5677
  /** Matches the logprob decoding failure `invalid or duplicate top logprob token`, which the ledger holds for the ledger's life. */
5190
5678
  export declare const DETERMINISTIC_JUDGE_ERROR: RegExp;
5191
5679
 
5192
5680
  /**
5193
- * Estimates the context-token footprint of a batch of messages — each message's content plus
5681
+ * Digests held messages, lookup call context, stored copies, and sentence receipts using canonical text.
5682
+ * This non-cryptographic checksum detects host edits and makes no security claim.
5683
+ * @param exchanges - The stored exchange entries
5684
+ * @param messages - The conversation holding their messages
5685
+ * @returns The hexadecimal checksum, or undefined when a required message is absent or canonical encoding fails
5686
+ * @example
5687
+ * ```ts
5688
+ * digestLedgerWindow([], []) // a deterministic hexadecimal checksum
5689
+ * ```
5690
+ */
5691
+ export declare function digestLedgerWindow(exchanges: readonly LedgerExchangeSnapshot[], messages: readonly Message[]): string | undefined;
5692
+
5693
+ /**
5694
+ * Estimates the context-token footprint of a batch of messages — each message's content plus
5194
5695
  * {@link import('./constants.js').MESSAGE_TOKEN_OVERHEAD}, a tool-call JSON estimate, a thinking estimate, and
5195
5696
  * {@link import('./constants.js').IMAGE_TOKEN_ESTIMATE} for each attached image. The {@link estimateRequest} message term
5196
5697
  * for an agent's context budget (the
@@ -5249,8 +5750,8 @@ export declare function estimateRequest(request: ProviderRequest): number;
5249
5750
 
5250
5751
  /**
5251
5752
  * Estimates the context-token footprint of a string — the deterministic `ceil(length / 4)`
5252
- * character heuristic {@link estimateMessages} sums over a conversation's messages (the default
5253
- * context-budget estimator).
5753
+ * character heuristic {@link import('./agents/helpers.js').estimateMessages} sums over a conversation's
5754
+ * messages (the default context-budget estimator).
5254
5755
  *
5255
5756
  * @remarks
5256
5757
  * Approximates `ceil(length / 4)` (4 characters per token), so the same input always yields the same estimate (no model round-trip).
@@ -5455,8 +5956,9 @@ export declare function freezeJSON(value: unknown): unknown;
5455
5956
  * has left.
5456
5957
  *
5457
5958
  * @remarks
5458
- * `observe` rescales from the first call of each finished request with the overhead cost taken out,
5459
- * and keeps that request's calls for the marginal rate and the longest final completion for the reply
5959
+ * `observe` rescales from the first call only when `spared` is absent, zero, or at least `overhead`,
5960
+ * with `max(0, overhead - spared)` taken out. A partially spared call keeps the existing scale.
5961
+ * It keeps that request's calls for the marginal rate and the longest final completion for the reply
5460
5962
  * reserve after subtracting its thinking. `overhead` never changes after construction.
5461
5963
  * {@link GaugeOptions} defines the measured use, reply reserve, and recall-room formulas.
5462
5964
  * {@link LedgerOptions} defines the ledger's plan budget and recall close rule.
@@ -5502,7 +6004,10 @@ export declare class Gauge implements GaugeInterface {
5502
6004
  * @remarks
5503
6005
  * `estimate` is the `estimateMessages` estimate of the call's messages. `prompt` and `completion`
5504
6006
  * are the tokens the provider reported, absent when it reported none. `tools` is the count of tool
5505
- * definitions the call advertised.
6007
+ * definitions the call advertised. `spared` is the tokens of definitions it did not advertise;
6008
+ * estimated use subtracts it from overhead, floored at 0. Omission means 0. Observation rescales
6009
+ * only with exact overhead: `spared` absent or zero retains all overhead, and `spared` at or above
6010
+ * overhead retains none. A partially spared first call keeps the prior scale.
5506
6011
  * `thinking` estimates the completion tokens spent on thinking from its share of the generated
5507
6012
  * characters, rounded to the nearest integer and capped at `completion`. With replay `'none'`,
5508
6013
  * the measured call uses `prompt + completion - thinking`; other policies retain the whole
@@ -5510,6 +6015,8 @@ export declare class Gauge implements GaugeInterface {
5510
6015
  */
5511
6016
  export declare interface GaugeCall {
5512
6017
  readonly estimate: number;
6018
+ /** Tokens spared by tool definitions this call did not advertise. Default: 0. */
6019
+ readonly spared?: number;
5513
6020
  readonly prompt?: number;
5514
6021
  readonly completion?: number;
5515
6022
  readonly thinking?: number;
@@ -5580,7 +6087,8 @@ export declare interface GaugeInterface extends LedgerGauge {
5580
6087
  * nonnegative safe integer less than `capacity`; construction throws `LedgerError` with code
5581
6088
  * `'CAPACITY'` otherwise. `replay` names the thinking the next request carries. Default: `'none'`.
5582
6089
  * Measured use is `prompt + completion - (thinking ?? 0)` for `'none'`, and `prompt + completion`
5583
- * otherwise; absent completion counts as 0. Without prompt usage, use is `overhead + scale * estimate`.
6090
+ * otherwise; absent completion counts as 0. Without prompt usage, use is
6091
+ * `max(0, overhead - (spared ?? 0)) + scale * estimate`.
5584
6092
  * Capacity left is `max(0, capacity - used)`. The reply reserve adds recall uniform at the marginal
5585
6093
  * rate to the largest observed reply's `completion - (thinking ?? 0)` for every policy.
5586
6094
  * Without a positive reply observation, it prices the longest reply text at that rate. Recall room is
@@ -5627,6 +6135,23 @@ export declare function handleAgentQueueJob(registry: AgentRegistryInterface, pa
5627
6135
  */
5628
6136
  export declare function hasCalls(message: Pick<Message, 'calls'>): boolean;
5629
6137
 
6138
+ /**
6139
+ * Checks whether an eligible earlier message is absent from the prompt or incompletely covered.
6140
+ * A successful finding is held when a finding with the same canonical identity and text is fully received.
6141
+ * @param input - The messages, findings, and classification
6142
+ * @param request - The current request id; only messages before it count
6143
+ * @param requests - The marked request ids
6144
+ * @param notes - The annotation ids to exclude
6145
+ * @param messages - The seed tail and held exchange messages; lookup stubs retain their rendered text
6146
+ * @param lines - The receipts held by the window and the request copy together
6147
+ * @returns True if an eligible earlier message is absent or only partly covered; false otherwise
6148
+ * @example
6149
+ * ```ts
6150
+ * hasHiddenRecall(input, request.id, requests, notes, tail, lines) // whether to offer recall
6151
+ * ```
6152
+ */
6153
+ export declare function hasHiddenRecall(input: LedgerProjectionInput, request: string, requests: ReadonlySet<string>, notes: ReadonlySet<string>, messages: readonly Message[], lines: readonly LedgerReceipt[]): boolean;
6154
+
5630
6155
  /**
5631
6156
  * Identifies a lookup finding for projection by its tool name and normalized arguments.
5632
6157
  *
@@ -6028,6 +6553,20 @@ export declare function isAgentJobError(value: unknown): value is AgentJobError;
6028
6553
  */
6029
6554
  export declare function isAuthorityDecision(value: unknown): value is AuthorityDecision;
6030
6555
 
6556
+ /**
6557
+ * Checks whether a value is an authority verdict: `allow`, `ask`, or `deny`.
6558
+ *
6559
+ * @param value - The unknown verdict candidate
6560
+ * @returns True if the value names a verdict; false otherwise
6561
+ *
6562
+ * @example
6563
+ * ```ts
6564
+ * isAuthorityVerdict('ask') // true
6565
+ * isAuthorityVerdict('maybe') // false
6566
+ * ```
6567
+ */
6568
+ export declare function isAuthorityVerdict(value: unknown): value is AuthorityVerdict;
6569
+
6031
6570
  /**
6032
6571
  * Narrows an unknown caught value to a {@link ContextError} through its identity brand and declared members, so a
6033
6572
  * `catch` can branch on its `code`.
@@ -6097,12 +6636,12 @@ export declare function isConversationError(value: unknown): value is Conversati
6097
6636
  * valid {@link Message} ({@link isMessage}), and optional valid `judgments` — enough to safely
6098
6637
  * impose the
6099
6638
  * {@link ConversationSnapshot} type at a storage boundary without a cast. The structural twin of
6100
- * {@link import('@orkestrel/workspace').isWorkspaceSnapshot}. Unknown members are admitted, so a
6101
- * 0.0.29 snapshot that carries a conversation `summary` passes. A malformed blob (a non-record,
6102
- * a missing / non-string `id`, a non-array `sections` / `messages`, or any malformed
6103
- * element) resolves `false`, so a
6639
+ * {@link import('@orkestrel/workspace').isWorkspaceSnapshot}. The guard is exact: an unknown member, a
6640
+ * 0.0.35 snapshot's conversation `summary` included, and an own `undefined` `judgments` return
6641
+ * `false`, as a malformed blob (a non-record, a missing / non-string `id`, a non-array `sections` /
6642
+ * `messages`, or any malformed element) does, so a
6104
6643
  * {@link import('./stores/DatabaseConversationStore.js').DatabaseConversationStore}
6105
- * read yields `undefined` rather than a broken conversation. The guard is structural: it admits a
6644
+ * read refuses it rather than seating a broken conversation. The guard is structural: it admits a
6106
6645
  * stored `system` role and a repeated id, which `requireConversationSnapshot` and the
6107
6646
  * {@link import('./Conversation.js').Conversation} constructor then refuse as the stored-data
6108
6647
  * check a conversation runs at hydrate.
@@ -6144,14 +6683,37 @@ export declare function isFraction(value: unknown): value is number;
6144
6683
  export declare function isJudgeAbortError(value: unknown): value is JudgeAbortError;
6145
6684
 
6146
6685
  /**
6147
- * Checks whether a value is a judge entry: a string, a JSON record, or a JSON array.
6686
+ * Checks whether a value is a stored judge answer of the choice, score, or noul form.
6687
+ *
6688
+ * @remarks
6689
+ * Total: an untrusted input returns false. The guard is exact on the answer's own keys and reads each
6690
+ * probability as a finite number, with noul bounded to `[0, 1]`. Whether the answer fits
6691
+ * its question belongs to the write. Every
6692
+ * judgment of a hydrate reads this guard, so it counts keys by hand rather than through a built one,
6693
+ * and `judgeAnswerContract` holds it in lockstep: an answer the contract accepts passes here.
6694
+ *
6695
+ * @param value - The value to test
6696
+ * @returns True if the value has the shape of a {@link JudgeAnswer}; false otherwise
6697
+ * @example
6698
+ * ```ts
6699
+ * isJudgeAnswer({ form: 'noul', noul: 0.9 }) // true
6700
+ * isJudgeAnswer({ form: 'choice', probabilities: { billing: 1 } }) // true
6701
+ * isJudgeAnswer({ form: 'noul', noul: 0.9, note: 'extra' }) // false
6702
+ * ```
6703
+ */
6704
+ export declare function isJudgeAnswer(value: unknown): value is JudgeAnswer;
6705
+
6706
+ /**
6707
+ * Checks whether a value is a judge entry: a non-empty string, a non-empty JSON record, or a non-empty
6708
+ * JSON array.
6148
6709
  *
6149
6710
  * @remarks
6150
- * Total: a cycle, a non-JSON member, a class instance, and an untrusted input return false. `null`
6151
- * is not an entry; a criteria guard admits it where the protocol keeps it.
6711
+ * Total: a cycle, a non-JSON member, a class instance, and an untrusted input return false. `''`,
6712
+ * `[]`, and `{}` give a judge nothing to read, so they return false. `null` is not an entry; a
6713
+ * criteria guard admits it where the protocol keeps it.
6152
6714
  *
6153
6715
  * @param value - The unknown entry candidate
6154
- * @returns True if the value is a string or JSON structure the model can read; false otherwise
6716
+ * @returns True if the value is a non-empty string or JSON structure the model can read; false otherwise
6155
6717
  * @example
6156
6718
  * ```ts
6157
6719
  * isJudgeEntry('Customer asks for a refund') // true
@@ -6180,8 +6742,10 @@ export declare function isJudgeError(value: unknown): value is JudgeError;
6180
6742
  * @remarks
6181
6743
  * Total: an untrusted input returns false. A choice needs at least 2 options and a score at least 2
6182
6744
  * levels, because the confidence formula divides by the candidate count; a description or a level
6183
- * can be `null`. `instructions` and noul `criteria` are omitted when absent and never `null`.
6184
- * Server limits on option, level, and question counts are left to the server.
6745
+ * can be `null`. `instructions` and noul `criteria` are omitted when absent and never `null`. The
6746
+ * guard is exact on the question's own keys: an unknown member, and an own `undefined` optional,
6747
+ * return false, as `judgeQuestionContract` does. Server limits on option, level, and question counts
6748
+ * are left to the server.
6185
6749
  *
6186
6750
  * @param value - The unknown question candidate
6187
6751
  * @returns True if the value is a question the judge engine can send; false otherwise
@@ -6199,11 +6763,13 @@ export declare function isJudgeQuestion(value: unknown): value is JudgeQuestion;
6199
6763
  * Checks whether a stored judgment carries a valid question and exactly one answer or refusal.
6200
6764
  *
6201
6765
  * @remarks
6202
- * Unknown members, malformed members, and unreadable inputs return false. Answer fields follow
6203
- * the root judge value types; this storage guard does not impose a wire's probability or
6204
- * candidate limits. The `time`, `noul`, and probability numbers must be finite, because a stored
6205
- * record is owned through JSON, which turns `NaN` and the infinities into `null`; so every record
6206
- * this guard accepts hydrates through a `JudgmentManager`.
6766
+ * Unknown members, malformed members, and unreadable inputs return false, the answer's and the
6767
+ * refusal's own included. Answer fields follow the root judge value types; this storage guard does not
6768
+ * impose a wire's probability or candidate limits, and the ties an answer holds to its question run
6769
+ * where a judgment is written, because records written before them can miss them. The `time`, `noul`,
6770
+ * and probability numbers must be finite, because a stored record is owned through JSON, which turns
6771
+ * `NaN` and the infinities into `null`; so every record this guard accepts hydrates through a
6772
+ * `JudgmentManager`.
6207
6773
  *
6208
6774
  * @param value - The unknown stored record
6209
6775
  * @returns True if the record satisfies the judgment contract; false otherwise
@@ -6229,6 +6795,25 @@ export declare const isJudgment: Guard<Judgment>;
6229
6795
  */
6230
6796
  export declare function isLedgerError(value: unknown): value is LedgerError;
6231
6797
 
6798
+ /**
6799
+ * Checks whether a value holds the wording a ledger files with: a choice `category` question whose
6800
+ * criteria describe every category, a non-empty `topic` string, and noul `amends` and `supersedes`
6801
+ * questions.
6802
+ *
6803
+ * @remarks
6804
+ * A ledger asks these on every message, so a hole in them would otherwise surface as filing that quietly
6805
+ * stays undecided. Total: an unreadable member returns false.
6806
+ *
6807
+ * @param value - The value to inspect
6808
+ * @returns True if the value holds the wording the ledger's questions read; false otherwise
6809
+ * @example
6810
+ * ```ts
6811
+ * isLedgerQuestion(LEDGER_QUESTIONS) // true
6812
+ * isLedgerQuestion({ topic: 'Does it concern this?' }) // false
6813
+ * ```
6814
+ */
6815
+ export declare function isLedgerQuestion(value: unknown): value is LedgerQuestion;
6816
+
6232
6817
  /**
6233
6818
  * Checks whether a value is a ledger snapshot whose marked ids name messages of its own conversation.
6234
6819
  *
@@ -6237,10 +6822,13 @@ export declare function isLedgerError(value: unknown): value is LedgerError;
6237
6822
  * dense arrays of strings. Each request and note id must name a `user` message of
6238
6823
  * `conversation.messages` and each failure id a `tool` message, so an id only a section original
6239
6824
  * holds is refused. A `gauge`, when present, must hold a finite `scale` greater than 0 and a finite
6240
- * `overhead` of at least 0. Unknown members are admitted. Unreadable members and untrusted inputs
6241
- * return false. The guard is structural: it admits a conversation holding a stored `system` role
6825
+ * `overhead` of at least 0. The guard is exact: an unknown member and an own `undefined` `gauge` return
6826
+ * false, at the snapshot and in its `gauge`. Unreadable members and untrusted inputs return false. The
6827
+ * guard is structural: it admits a conversation holding a stored `system` role
6242
6828
  * or a repeated id, which `requireConversationSnapshot` and the `Conversation` constructor then
6243
6829
  * refuse as the stored-data check a ledger's hydrate runs.
6830
+ * A present `window` must be nonempty and exactly shaped. This guard does not audit its references
6831
+ * or sentence ranges. Hydration discards the window when its digest disagrees or cannot be computed.
6244
6832
  *
6245
6833
  * @param value - The value to inspect, such as a parsed checkpoint
6246
6834
  * @returns True if the value has the shape of a ledger snapshot whose marked ids name messages of its own conversation; false otherwise
@@ -6253,15 +6841,28 @@ export declare function isLedgerError(value: unknown): value is LedgerError;
6253
6841
  */
6254
6842
  export declare function isLedgerSnapshot(value: unknown): value is LedgerSnapshot;
6255
6843
 
6844
+ /**
6845
+ * Checks whether a value has the exact shape of a nonempty exchange window.
6846
+ * @param value - The untrusted window
6847
+ * @returns True if the window and its members are well shaped; false otherwise
6848
+ * @example
6849
+ * ```ts
6850
+ * isLedgerWindowSnapshot({ digest: 'checksum', exchanges: [{ request: 'request', reply: 'reply', lines: [] }], amendments: [] }) // true
6851
+ * ```
6852
+ */
6853
+ export declare function isLedgerWindowSnapshot(value: unknown): value is LedgerWindowSnapshot;
6854
+
6256
6855
  /**
6257
6856
  * Checks whether a value is a stored memo revision: a record with a string `id`, `name`,
6258
6857
  * `description`, and `content`, a finite `time`, and an optional `origin`.
6259
6858
  *
6260
6859
  * @remarks
6261
6860
  * An `origin`, when present, is a record with a string `conversation` and an optional string
6262
- * `message`. Unknown members are admitted. The `time` must be finite, because a stored revision
6263
- * is owned through JSON, which turns `NaN` and the infinities into `null`. Malformed and
6264
- * unreadable inputs, a throwing getter or a revoked proxy included, return false.
6861
+ * `message`. The guard is exact: an unknown member and an own `undefined` optional return false. The
6862
+ * `time` must be finite, because a stored revision is owned through JSON, which turns `NaN` and the
6863
+ * infinities into `null`. Malformed and unreadable inputs, a throwing getter or a revoked proxy
6864
+ * included, return false. Every revision of a hydrate reads this guard, so it counts keys by hand
6865
+ * rather than through a built one, and `memoSnapshotContract` holds it in lockstep.
6265
6866
  *
6266
6867
  * @param value - The value to test
6267
6868
  * @returns True if `value` has the shape of a {@link Memo}; false otherwise
@@ -6274,15 +6875,33 @@ export declare function isLedgerSnapshot(value: unknown): value is LedgerSnapsho
6274
6875
  * isMemo({ id: 'm1', name: 'tone', description: 'Prefers short replies.', content: 'Answer briefly.', time: Number.NaN }) // false
6275
6876
  * ```
6276
6877
  */
6277
- export declare const isMemo: Guard<Memo>;
6878
+ export declare function isMemo(value: unknown): value is Memo;
6879
+
6880
+ /**
6881
+ * Checks whether a value is a memo's origin: a record with a string `conversation` and an optional
6882
+ * string `message`.
6883
+ *
6884
+ * @remarks
6885
+ * The guard is exact: an unknown member and an own `undefined` `message` return false. Malformed and
6886
+ * unreadable inputs return false.
6887
+ *
6888
+ * @param value - The value to test
6889
+ * @returns True if `value` has the shape of a {@link MemoOrigin}; false otherwise
6890
+ * @example
6891
+ * ```ts
6892
+ * isMemoOrigin({ conversation: 'c1', message: 'm1' }) // true
6893
+ * isMemoOrigin({ conversation: 'c1', extra: true }) // false
6894
+ * ```
6895
+ */
6896
+ export declare function isMemoOrigin(value: unknown): value is MemoOrigin;
6278
6897
 
6279
6898
  /**
6280
6899
  * Checks whether a value is a stored memo set: a record with a string `id` and a dense `memos`
6281
6900
  * array of {@link isMemo} values.
6282
6901
  *
6283
6902
  * @remarks
6284
- * Unknown members are admitted. A sparse `memos` array, a malformed revision, and unreadable
6285
- * inputs, a throwing getter or a revoked proxy included, return false.
6903
+ * The guard is exact: an unknown member returns false, as a sparse `memos` array, a malformed
6904
+ * revision, and unreadable inputs, a throwing getter or a revoked proxy included, do.
6286
6905
  *
6287
6906
  * @param value - The value to test (an opaque storage read)
6288
6907
  * @returns True if `value` has the shape of a {@link MemoSnapshot}; false otherwise
@@ -6303,8 +6922,9 @@ export declare function isMemoSnapshot(value: unknown): value is MemoSnapshot;
6303
6922
  * @remarks
6304
6923
  * Roles belong to MessageRole, image elements are strings, `thinking` is a string, and `call` is a string on any
6305
6924
  * role, as the flat Message type admits. Tool arguments may carry non-JSON values, as the
6306
- * domain type permits; the message wire contract is narrower. Unreadable fields and untrusted
6307
- * inputs return false.
6925
+ * domain type permits; the message wire contract is narrower. The guard is exact on the message's own
6926
+ * keys: an unknown member, and an own `undefined` optional, return false. Unreadable fields and
6927
+ * untrusted inputs return false.
6308
6928
  *
6309
6929
  * @param value - The unknown message candidate
6310
6930
  * @returns True if the domain message fields are valid; false otherwise
@@ -6318,6 +6938,25 @@ export declare function isMemoSnapshot(value: unknown): value is MemoSnapshot;
6318
6938
  */
6319
6939
  export declare function isMessage(value: unknown): value is Message;
6320
6940
 
6941
+ /**
6942
+ * Checks whether a value is a message input a conversation can store: a string `content`, and `calls`,
6943
+ * `call`, `images`, and `thinking` absent or of their declared types.
6944
+ *
6945
+ * @remarks
6946
+ * A hand guard, because `add` checks every message: it reads the members once and composes no record
6947
+ * guard. The role is `requireRole`'s to refuse, so its text can name the role received. Unknown members
6948
+ * are left behind by the store. An unreadable member returns false.
6949
+ *
6950
+ * @param value - The unknown input candidate
6951
+ * @returns True if the input's members are valid; false otherwise
6952
+ * @example
6953
+ * ```ts
6954
+ * isMessageInput({ role: 'user', content: 'hi' }) // true
6955
+ * isMessageInput({ role: 'user' }) // false
6956
+ * ```
6957
+ */
6958
+ export declare function isMessageInput(value: unknown): value is MessageInput;
6959
+
6321
6960
  /**
6322
6961
  * Checks whether a value is a non-negative safe integer, `-0` included.
6323
6962
  *
@@ -6346,6 +6985,7 @@ export declare function isNonNegativeSafeInteger(value: unknown): value is numbe
6346
6985
  * @example
6347
6986
  * ```ts
6348
6987
  * isPositiveSafeInteger(4096) // true
6988
+ * isPositiveSafeInteger(0) // false
6349
6989
  * ```
6350
6990
  */
6351
6991
  export declare function isPositiveSafeInteger(value: unknown): value is number;
@@ -6380,6 +7020,28 @@ export declare function isProviderAbortError(value: unknown): value is ProviderA
6380
7020
  */
6381
7021
  export declare function isProviderError(value: unknown): value is ProviderError;
6382
7022
 
7023
+ /**
7024
+ * Checks whether a value carries the members {@link ProviderResult} publishes: a string `content`, and
7025
+ * `thinking`, `tools`, `usage`, and `truncated` absent or of their published types.
7026
+ *
7027
+ * @remarks
7028
+ * A provider is a foreign interface, so the guard is open: unknown members and a class instance pass,
7029
+ * and each `usage` count is a finite nonnegative number with no integer check. An unreadable member
7030
+ * returns false. {@link import('./helpers.js').requireProviderResult} runs it on an owned copy, the one
7031
+ * door a run's result crosses.
7032
+ *
7033
+ * @param value - The unknown result candidate
7034
+ * @returns True if the value satisfies the published result; false otherwise
7035
+ *
7036
+ * @example
7037
+ * ```ts
7038
+ * isProviderResult({ content: 'answer', extra: true }) // true
7039
+ * isProviderResult({}) // false
7040
+ * isProviderResult({ content: 'answer', usage: { prompt: -1, completion: 0, total: 0 } }) // false
7041
+ * ```
7042
+ */
7043
+ export declare const isProviderResult: Guard<ProviderResult>;
7044
+
6383
7045
  /**
6384
7046
  * Checks whether an `unknown` is structurally a {@link Section} record — a `string` `id` and
6385
7047
  * `summary` beside a `messages` array of valid {@link Message} records, the per-section step of
@@ -6390,8 +7052,8 @@ export declare function isProviderError(value: unknown): value is ProviderError;
6390
7052
  * A total guard (it never throws — untrusted input, a throwing getter included, returns
6391
7053
  * `false`). It checks the shape of the section: a record with a `string` `id`, a `string`
6392
7054
  * `summary`, and a dense `messages` array every element of which is a valid {@link Message}
6393
- * record ({@link isMessage}); a sparse `messages` array is refused. Enough to safely impose
6394
- * the {@link Section} type at a storage boundary without a cast.
7055
+ * record ({@link isMessage}), and no other member; a sparse `messages` array is refused. Enough to
7056
+ * safely impose the {@link Section} type at a storage boundary without a cast.
6395
7057
  *
6396
7058
  * @param value - The value to test (one element of a snapshot's `sections` array)
6397
7059
  * @returns True if `value` has the structural shape of a {@link Section}; false otherwise
@@ -6489,9 +7151,50 @@ export declare class JudgeAbortError extends Error {
6489
7151
  /** Names one answer by its form; it stores only the distribution a server returned. */
6490
7152
  export declare type JudgeAnswer = ChoiceAnswer | ScoreAnswer | NoulAnswer;
6491
7153
 
7154
+ /** Reads the faults of a refused judge answer. */
7155
+ export declare const judgeAnswerContract: ContractInterface<Readonly<{
7156
+ form: "choice";
7157
+ probabilities: {
7158
+ readonly [k: string]: number;
7159
+ };
7160
+ } & {}> | Readonly<{
7161
+ form: "score";
7162
+ probabilities: readonly number[];
7163
+ } & {}> | Readonly<{
7164
+ form: "noul";
7165
+ noul: number;
7166
+ } & {}>>;
7167
+
7168
+ /**
7169
+ * Describes a judge answer: one exact object per form, each probability in `[0, 1]`.
7170
+ *
7171
+ * @remarks
7172
+ * The ties an answer holds to its question run at the write doors through `scanJudgmentTies`, which a
7173
+ * shape over the answer alone cannot state.
7174
+ */
7175
+ export declare const judgeAnswerShape: UnionShape<readonly [ObjectShape< {
7176
+ form: LiteralShape<readonly ["choice"]>;
7177
+ probabilities: ObjectShape<Record<never, never>, NumberShape>;
7178
+ }, boolean | ContractShape>, ObjectShape< {
7179
+ form: LiteralShape<readonly ["score"]>;
7180
+ probabilities: ArrayShape<NumberShape>;
7181
+ }, boolean | ContractShape>, ObjectShape< {
7182
+ form: LiteralShape<readonly ["noul"]>;
7183
+ noul: NumberShape;
7184
+ }, boolean | ContractShape>]>;
7185
+
6492
7186
  /** Carries text or structured JSON the model reads; mirrors the TypeSafe `EntryType` without its null arm. */
6493
7187
  export declare type JudgeEntry = string | JSONRecord | readonly JSONValue[];
6494
7188
 
7189
+ /**
7190
+ * Describes the text or JSON a judge reads: a non-empty string, a non-empty JSON array, or a JSON record.
7191
+ *
7192
+ * @remarks
7193
+ * A shape has no `minProperties`, so this one admits the empty record that `isJudgeEntry` refuses;
7194
+ * the guard is the door, and this shape only fills a refusal's faults.
7195
+ */
7196
+ export declare const judgeEntryShape: UnionShape<readonly [StringShape, ArrayShape<JSONShape>, ObjectShape<Record<never, never>, JSONShape>]>;
7197
+
6495
7198
  /**
6496
7199
  * Reports a coded judge failure with its HTTP status and underlying cause when available.
6497
7200
  *
@@ -6506,6 +7209,8 @@ export declare class JudgeError extends Error {
6506
7209
  readonly code: JudgeErrorCode;
6507
7210
  /** Holds the response status for an HTTP failure, or undefined for other codes. */
6508
7211
  readonly status: number | undefined;
7212
+ /** Holds the values that locate the failure, such as the `faults` of a refused question, or `undefined` when none were supplied. */
7213
+ readonly context: Readonly<Record<string, unknown>> | undefined;
6509
7214
  constructor(code: JudgeErrorCode, message: string, options?: ProviderErrorOptions);
6510
7215
  }
6511
7216
 
@@ -6531,6 +7236,67 @@ export declare interface JudgeInterface {
6531
7236
  /** Names one question by its form, the protocol's type field under the fleet's named discriminant. */
6532
7237
  export declare type JudgeQuestion = ChoiceQuestion | ScoreQuestion | NoulQuestion;
6533
7238
 
7239
+ /** Reads the faults of a refused judge question. */
7240
+ export declare const judgeQuestionContract: ContractInterface<Readonly<{
7241
+ form: "choice";
7242
+ criteria: {
7243
+ readonly [k: string]: string | readonly JSONValue[] | {
7244
+ readonly [k: string]: JSONValue;
7245
+ } | null;
7246
+ };
7247
+ } & {
7248
+ instructions?: string | readonly JSONValue[] | {
7249
+ readonly [k: string]: JSONValue;
7250
+ };
7251
+ }> | Readonly<{
7252
+ form: "score";
7253
+ criteria: readonly (string | readonly JSONValue[] | {
7254
+ readonly [k: string]: JSONValue;
7255
+ } | null)[];
7256
+ } & {
7257
+ instructions?: string | readonly JSONValue[] | {
7258
+ readonly [k: string]: JSONValue;
7259
+ };
7260
+ }> | Readonly<{
7261
+ form: "noul";
7262
+ } & {
7263
+ instructions?: string | readonly JSONValue[] | {
7264
+ readonly [k: string]: JSONValue;
7265
+ };
7266
+ criteria?: Readonly<{} & {
7267
+ true?: string | readonly JSONValue[] | {
7268
+ readonly [k: string]: JSONValue;
7269
+ };
7270
+ false?: string | readonly JSONValue[] | {
7271
+ readonly [k: string]: JSONValue;
7272
+ };
7273
+ }>;
7274
+ }>>;
7275
+
7276
+ /**
7277
+ * Describes a judge question: one exact object per form, the schema an LLM-facing wire can publish.
7278
+ *
7279
+ * @remarks
7280
+ * `isJudgeQuestion` is the door; this shape fills a refusal's faults. A choice needing at least 2
7281
+ * options is the guard's alone, because a shape has no `minProperties`.
7282
+ */
7283
+ export declare const judgeQuestionShape: UnionShape<readonly [ObjectShape< {
7284
+ form: LiteralShape<readonly ["choice"]>;
7285
+ instructions: OptionalShape<UnionShape<readonly [StringShape, ArrayShape<JSONShape>, ObjectShape<Record<never, never>, JSONShape>]>>;
7286
+ criteria: ObjectShape<Record<never, never>, NullableShape<UnionShape<readonly [StringShape, ArrayShape<JSONShape>, ObjectShape<Record<never, never>, JSONShape>]>>>;
7287
+ }, boolean | ContractShape>, ObjectShape< {
7288
+ form: LiteralShape<readonly ["score"]>;
7289
+ instructions: OptionalShape<UnionShape<readonly [StringShape, ArrayShape<JSONShape>, ObjectShape<Record<never, never>, JSONShape>]>>;
7290
+ criteria: ArrayShape<NullableShape<UnionShape<readonly [StringShape, ArrayShape<JSONShape>, ObjectShape<Record<never, never>, JSONShape>]>>>;
7291
+ }, boolean | ContractShape>, ObjectShape< {
7292
+ form: LiteralShape<readonly ["noul"]>;
7293
+ instructions: OptionalShape<UnionShape<readonly [StringShape, ArrayShape<JSONShape>, ObjectShape<Record<never, never>, JSONShape>]>>;
7294
+ criteria: OptionalShape<ObjectShape< {
7295
+ true: OptionalShape<UnionShape<readonly [StringShape, ArrayShape<JSONShape>, ObjectShape<Record<never, never>, JSONShape>]>>;
7296
+ false: OptionalShape<UnionShape<readonly [StringShape, ArrayShape<JSONShape>, ObjectShape<Record<never, never>, JSONShape>]>>;
7297
+ }, boolean | ContractShape>>;
7298
+ }, boolean | ContractShape>]>;
7299
+
6534
7300
  /** Carries one state and the questions asked about it, keyed by caller ids the prompt never carries; each question is evaluated on its own. */
6535
7301
  export declare interface JudgeRequest {
6536
7302
  readonly state: JudgeEntry;
@@ -6562,6 +7328,118 @@ export declare interface Judgment {
6562
7328
  readonly usage?: TokenUsage;
6563
7329
  }
6564
7330
 
7331
+ /** Reads the faults of a refused judgment. */
7332
+ export declare const judgmentContract: ContractInterface<Readonly<{
7333
+ id: string;
7334
+ question: Readonly<{
7335
+ form: "choice";
7336
+ criteria: {
7337
+ readonly [k: string]: string | readonly JSONValue[] | {
7338
+ readonly [k: string]: JSONValue;
7339
+ } | null;
7340
+ };
7341
+ } & {
7342
+ instructions?: string | readonly JSONValue[] | {
7343
+ readonly [k: string]: JSONValue;
7344
+ };
7345
+ }> | Readonly<{
7346
+ form: "score";
7347
+ criteria: readonly (string | readonly JSONValue[] | {
7348
+ readonly [k: string]: JSONValue;
7349
+ } | null)[];
7350
+ } & {
7351
+ instructions?: string | readonly JSONValue[] | {
7352
+ readonly [k: string]: JSONValue;
7353
+ };
7354
+ }> | Readonly<{
7355
+ form: "noul";
7356
+ } & {
7357
+ instructions?: string | readonly JSONValue[] | {
7358
+ readonly [k: string]: JSONValue;
7359
+ };
7360
+ criteria?: Readonly<{} & {
7361
+ true?: string | readonly JSONValue[] | {
7362
+ readonly [k: string]: JSONValue;
7363
+ };
7364
+ false?: string | readonly JSONValue[] | {
7365
+ readonly [k: string]: JSONValue;
7366
+ };
7367
+ }>;
7368
+ }>;
7369
+ model: string;
7370
+ sources: readonly string[];
7371
+ state: string;
7372
+ time: number;
7373
+ answer: Readonly<{
7374
+ form: "choice";
7375
+ probabilities: {
7376
+ readonly [k: string]: number;
7377
+ };
7378
+ } & {}> | Readonly<{
7379
+ form: "score";
7380
+ probabilities: readonly number[];
7381
+ } & {}> | Readonly<{
7382
+ form: "noul";
7383
+ noul: number;
7384
+ } & {}>;
7385
+ } & {
7386
+ usage?: Readonly<{
7387
+ prompt: number;
7388
+ completion: number;
7389
+ total: number;
7390
+ } & {}>;
7391
+ }> | Readonly<{
7392
+ id: string;
7393
+ question: Readonly<{
7394
+ form: "choice";
7395
+ criteria: {
7396
+ readonly [k: string]: string | readonly JSONValue[] | {
7397
+ readonly [k: string]: JSONValue;
7398
+ } | null;
7399
+ };
7400
+ } & {
7401
+ instructions?: string | readonly JSONValue[] | {
7402
+ readonly [k: string]: JSONValue;
7403
+ };
7404
+ }> | Readonly<{
7405
+ form: "score";
7406
+ criteria: readonly (string | readonly JSONValue[] | {
7407
+ readonly [k: string]: JSONValue;
7408
+ } | null)[];
7409
+ } & {
7410
+ instructions?: string | readonly JSONValue[] | {
7411
+ readonly [k: string]: JSONValue;
7412
+ };
7413
+ }> | Readonly<{
7414
+ form: "noul";
7415
+ } & {
7416
+ instructions?: string | readonly JSONValue[] | {
7417
+ readonly [k: string]: JSONValue;
7418
+ };
7419
+ criteria?: Readonly<{} & {
7420
+ true?: string | readonly JSONValue[] | {
7421
+ readonly [k: string]: JSONValue;
7422
+ };
7423
+ false?: string | readonly JSONValue[] | {
7424
+ readonly [k: string]: JSONValue;
7425
+ };
7426
+ }>;
7427
+ }>;
7428
+ model: string;
7429
+ sources: readonly string[];
7430
+ state: string;
7431
+ time: number;
7432
+ refusal: Readonly<{
7433
+ missing: readonly string[];
7434
+ } & {}>;
7435
+ } & {
7436
+ usage?: Readonly<{
7437
+ prompt: number;
7438
+ completion: number;
7439
+ total: number;
7440
+ } & {}>;
7441
+ }>>;
7442
+
6565
7443
  /** Supplies an answered or refused question for storage before its time is stamped. */
6566
7444
  export declare interface JudgmentInput {
6567
7445
  readonly id: string;
@@ -6661,6 +7539,83 @@ export declare interface JudgmentManagerInterface {
6661
7539
  resolve(judge: JudgeInterface, request: JudgeRequest, sources: readonly string[], signal: AbortSignal): Promise<readonly Judgment[]>;
6662
7540
  }
6663
7541
 
7542
+ /**
7543
+ * Describes a stored judgment: exactly one of an answer or a refusal, with its question, sources,
7544
+ * state, model, and storage time.
7545
+ *
7546
+ * @remarks
7547
+ * `isJudgment` is the door a hydrate reads and this shape fills a refusal's faults, because hydrate is
7548
+ * a per-element path. A lockstep test holds that `is` implies the guard.
7549
+ */
7550
+ export declare const judgmentShape: UnionShape<readonly [ObjectShape< {
7551
+ id: StringShape;
7552
+ question: UnionShape<readonly [ObjectShape< {
7553
+ form: LiteralShape<readonly ["choice"]>;
7554
+ instructions: OptionalShape<UnionShape<readonly [StringShape, ArrayShape<JSONShape>, ObjectShape<Record<never, never>, JSONShape>]>>;
7555
+ criteria: ObjectShape<Record<never, never>, NullableShape<UnionShape<readonly [StringShape, ArrayShape<JSONShape>, ObjectShape<Record<never, never>, JSONShape>]>>>;
7556
+ }, boolean | ContractShape>, ObjectShape< {
7557
+ form: LiteralShape<readonly ["score"]>;
7558
+ instructions: OptionalShape<UnionShape<readonly [StringShape, ArrayShape<JSONShape>, ObjectShape<Record<never, never>, JSONShape>]>>;
7559
+ criteria: ArrayShape<NullableShape<UnionShape<readonly [StringShape, ArrayShape<JSONShape>, ObjectShape<Record<never, never>, JSONShape>]>>>;
7560
+ }, boolean | ContractShape>, ObjectShape< {
7561
+ form: LiteralShape<readonly ["noul"]>;
7562
+ instructions: OptionalShape<UnionShape<readonly [StringShape, ArrayShape<JSONShape>, ObjectShape<Record<never, never>, JSONShape>]>>;
7563
+ criteria: OptionalShape<ObjectShape< {
7564
+ true: OptionalShape<UnionShape<readonly [StringShape, ArrayShape<JSONShape>, ObjectShape<Record<never, never>, JSONShape>]>>;
7565
+ false: OptionalShape<UnionShape<readonly [StringShape, ArrayShape<JSONShape>, ObjectShape<Record<never, never>, JSONShape>]>>;
7566
+ }, boolean | ContractShape>>;
7567
+ }, boolean | ContractShape>]>;
7568
+ model: StringShape;
7569
+ sources: ArrayShape<StringShape>;
7570
+ state: StringShape;
7571
+ time: NumberShape;
7572
+ usage: OptionalShape<ObjectShape< {
7573
+ prompt: NumberShape;
7574
+ completion: NumberShape;
7575
+ total: NumberShape;
7576
+ }, boolean | ContractShape>>;
7577
+ answer: UnionShape<readonly [ObjectShape< {
7578
+ form: LiteralShape<readonly ["choice"]>;
7579
+ probabilities: ObjectShape<Record<never, never>, NumberShape>;
7580
+ }, boolean | ContractShape>, ObjectShape< {
7581
+ form: LiteralShape<readonly ["score"]>;
7582
+ probabilities: ArrayShape<NumberShape>;
7583
+ }, boolean | ContractShape>, ObjectShape< {
7584
+ form: LiteralShape<readonly ["noul"]>;
7585
+ noul: NumberShape;
7586
+ }, boolean | ContractShape>]>;
7587
+ }, boolean | ContractShape>, ObjectShape< {
7588
+ id: StringShape;
7589
+ question: UnionShape<readonly [ObjectShape< {
7590
+ form: LiteralShape<readonly ["choice"]>;
7591
+ instructions: OptionalShape<UnionShape<readonly [StringShape, ArrayShape<JSONShape>, ObjectShape<Record<never, never>, JSONShape>]>>;
7592
+ criteria: ObjectShape<Record<never, never>, NullableShape<UnionShape<readonly [StringShape, ArrayShape<JSONShape>, ObjectShape<Record<never, never>, JSONShape>]>>>;
7593
+ }, boolean | ContractShape>, ObjectShape< {
7594
+ form: LiteralShape<readonly ["score"]>;
7595
+ instructions: OptionalShape<UnionShape<readonly [StringShape, ArrayShape<JSONShape>, ObjectShape<Record<never, never>, JSONShape>]>>;
7596
+ criteria: ArrayShape<NullableShape<UnionShape<readonly [StringShape, ArrayShape<JSONShape>, ObjectShape<Record<never, never>, JSONShape>]>>>;
7597
+ }, boolean | ContractShape>, ObjectShape< {
7598
+ form: LiteralShape<readonly ["noul"]>;
7599
+ instructions: OptionalShape<UnionShape<readonly [StringShape, ArrayShape<JSONShape>, ObjectShape<Record<never, never>, JSONShape>]>>;
7600
+ criteria: OptionalShape<ObjectShape< {
7601
+ true: OptionalShape<UnionShape<readonly [StringShape, ArrayShape<JSONShape>, ObjectShape<Record<never, never>, JSONShape>]>>;
7602
+ false: OptionalShape<UnionShape<readonly [StringShape, ArrayShape<JSONShape>, ObjectShape<Record<never, never>, JSONShape>]>>;
7603
+ }, boolean | ContractShape>>;
7604
+ }, boolean | ContractShape>]>;
7605
+ model: StringShape;
7606
+ sources: ArrayShape<StringShape>;
7607
+ state: StringShape;
7608
+ time: NumberShape;
7609
+ usage: OptionalShape<ObjectShape< {
7610
+ prompt: NumberShape;
7611
+ completion: NumberShape;
7612
+ total: NumberShape;
7613
+ }, boolean | ContractShape>>;
7614
+ refusal: ObjectShape< {
7615
+ missing: ArrayShape<StringShape>;
7616
+ }, boolean | ContractShape>;
7617
+ }, boolean | ContractShape>]>;
7618
+
6664
7619
  /**
6665
7620
  * Serves one conversation through classified records, a bounded copy of each request turn that carries them, and a final answer pass.
6666
7621
  * @example
@@ -6678,7 +7633,8 @@ export declare class Ledger implements LedgerInterface {
6678
7633
  * @param options - The filing policy, capacity, and request bounds
6679
7634
  * @throws {LedgerError} Thrown when a threshold, share, capacity, limit, topic, lookup, or gauge is invalid
6680
7635
  * @throws {LedgerError} Thrown when `predict` is not a nonnegative safe integer less than `capacity` (code `'CAPACITY'`)
6681
- * @throws {LedgerError} Thrown when `snapshot` is malformed or marks an id its conversation does not hold (code `'SNAPSHOT'`)
7636
+ * @throws {LedgerError} Thrown when `questions` fails `isLedgerQuestion` (code `'QUESTION'`)
7637
+ * @throws {LedgerError} Thrown when `snapshot` is malformed or marks an id its conversation does not hold (code `'SNAPSHOT'`, its faults under `context.faults`)
6682
7638
  * @throws {ConversationError} Thrown when `isLedgerSnapshot` admits `snapshot` but its conversation holds a `system` message (code `'ROLE'`) or repeats an id (code `'SNAPSHOT'`)
6683
7639
  */
6684
7640
  constructor(provider: ProviderInterface, options: LedgerOptions);
@@ -6706,15 +7662,15 @@ export declare class Ledger implements LedgerInterface {
6706
7662
  */
6707
7663
  calibrate(signal: AbortSignal): Promise<LedgerGauge>;
6708
7664
  /**
6709
- * Serializes the conversation, the marked ids, and the gauge into a snapshot a later ledger hydrates from.
6710
- * @returns The snapshot, each id list in conversation order and `gauge` present after the ledger holds one
7665
+ * Serializes the conversation, marked ids, gauge, and completed exchange window for a later ledger.
7666
+ * @returns The snapshot, each id list in conversation order, with a gauge and window only when held
6711
7667
  * @throws {AgentError} Thrown when a request or calibration is active (code `'CONCURRENCY'`)
6712
7668
  */
6713
7669
  snapshot(): LedgerSnapshot;
6714
7670
  /**
6715
7671
  * Appends a request and serves it, recovering an unfinished or rejected first pass with one answer pass.
6716
7672
  * A calibration call that reports no prompt usage, or a prompt usage of 0 or less, rejects with `LedgerError` code `'GAUGE'`; a provider error during calibration rejects with that error.
6717
- * When the answer pass rejects, `respond` rejects with that error. Every rejection leaves the ledger free for a later call.
7673
+ * When the answer pass rejects, `respond` rejects with that error, and under the default `strict` a judge failure or another selection failure rejects it too. A rejection belongs to its own call: the ledger stays free, and the next call asks the judge again about whatever is still unanswered.
6718
7674
  * @param content - The request text
6719
7675
  * @param signal - The caller's cancellation signal; an abort during calibration rejects with its reason
6720
7676
  * @returns The final pass, the usage of every pass, and the filing attempts of this request alone
@@ -6748,6 +7704,12 @@ export declare const LEDGER_OWNER_PREFIX = "owner:";
6748
7704
  */
6749
7705
  export declare const LEDGER_QUESTIONS: LedgerQuestion;
6750
7706
 
7707
+ /** Labels recalled conversation text by its origin. */
7708
+ export declare const LEDGER_RECALL_LABELS: Readonly<{
7709
+ request: "Earlier request:";
7710
+ reply: "Earlier reply:";
7711
+ }>;
7712
+
6751
7713
  /** Names the key of the record that holds the rules no owner claims. */
6752
7714
  export declare const LEDGER_RULES_KEY = "rules";
6753
7715
 
@@ -6783,15 +7745,19 @@ export declare const LEDGER_WORD: RegExp;
6783
7745
  * Selects the agent bounds, hooks, scheduler, and context libraries a ledger passes through to the agent it builds.
6784
7746
  *
6785
7747
  * @remarks
6786
- * `limit` must be a nonnegative safe integer. Default: the `DEFAULT_LEDGER_LIMIT` constant. The
7748
+ * `limit` must be a positive safe integer. Default: the `DEFAULT_LEDGER_LIMIT` constant. The
6787
7749
  * ledger owns every other agent option: the conversation, the tools, the selection handler, and
6788
7750
  * the scope. One memo set can serve many ledgers of one principal, and the plan prices what these
6789
7751
  * libraries add to the head. `scheduler` also reaches the ledger's classifier, which hands the host
6790
7752
  * a turn while it files, so a page passes it to keep the filing out of one long task. The classifier
6791
7753
  * and the loop race its yield against the run signal, so a scheduler that ignores its signal still
6792
- * ends on a cancel.
7754
+ * ends on a cancel. `strict` defaults to `true`: a judge failure or another selection failure rejects
7755
+ * that `respond` call after the `fault` event, and the next call asks the judge again about whatever is
7756
+ * still unanswered. With `strict: false` the request goes on with that question undecided, or from the
7757
+ * conversation's `view()`. A provider failure in the first pass is the one
7758
+ * failure the answer pass recovers under either value.
6793
7759
  */
6794
- export declare type LedgerAgentOptions = Pick<AgentOptions, 'limit' | 'timeout' | 'on' | 'scheduler' | 'instructions' | 'skills' | 'memos' | 'workspaces'>;
7760
+ export declare type LedgerAgentOptions = Pick<AgentOptions, 'limit' | 'timeout' | 'on' | 'scheduler' | 'instructions' | 'skills' | 'memos' | 'workspaces' | 'strict'>;
6795
7761
 
6796
7762
  /** Identifies an accepted direct message amendment whose sentence scope remains unresolved. */
6797
7763
  export declare interface LedgerAmendment {
@@ -6839,6 +7805,14 @@ export declare interface LedgerCorrectionOptions {
6839
7805
  readonly narrow?: boolean;
6840
7806
  }
6841
7807
 
7808
+ /** Carries a planned copy and its validity evidence to request settlement. */
7809
+ export declare interface LedgerDraft {
7810
+ readonly copy: Message;
7811
+ readonly lines: readonly LedgerOccurrence[];
7812
+ readonly evidence: LedgerEvidence;
7813
+ readonly window: readonly LedgerExchange[];
7814
+ }
7815
+
6842
7816
  /**
6843
7817
  * Lists the registry ids and owner ids a text names.
6844
7818
  *
@@ -6853,10 +7827,10 @@ export declare type LedgerEntityHandler = (text: string, partial: boolean) => Re
6853
7827
  * carrying the machine-readable `code`.
6854
7828
  *
6855
7829
  * @remarks
6856
- * A threshold, share, capacity, limit, topic, lookup, or gauge outside its bounds is a programmer
6857
- * error and throws this with the matching {@link LedgerErrorCode}. A calibration call that reports
7830
+ * A threshold, share, capacity, limit, topic, lookup, question, or gauge outside its bounds is a
7831
+ * programmer error and throws this with the matching {@link LedgerErrorCode}. A calibration call that reports
6858
7832
  * no prompt usage throws this with `'GAUGE'`. A snapshot option that `isLedgerSnapshot` refuses
6859
- * throws this with `'SNAPSHOT'`. Narrow a caught value with {@link isLedgerError} and
7833
+ * throws this with `'SNAPSHOT'`, its `context` holding the `faults`. Narrow a caught value with {@link isLedgerError} and
6860
7834
  * branch on `error.code`. A selection without an active `respond` call, for a conversation other
6861
7835
  * than the ledger's, or for a request other than that call's request or a ledger note, reports
6862
7836
  * `'REQUEST'` through the selection's fault.
@@ -6864,13 +7838,16 @@ export declare type LedgerEntityHandler = (text: string, partial: boolean) => Re
6864
7838
  export declare class LedgerError extends Error {
6865
7839
  /** Names the machine-readable condition; the {@link LedgerErrorCode} union describes each code. */
6866
7840
  readonly code: LedgerErrorCode;
7841
+ /** Holds the values that locate the failure, such as the `faults` of a refused snapshot, or `undefined` when none were supplied. */
7842
+ readonly context: Readonly<Record<string, unknown>> | undefined;
6867
7843
  /**
6868
7844
  * Records the failure condition and its description.
6869
7845
  *
6870
7846
  * @param code - The machine-readable condition, exposed as `error.code`
6871
7847
  * @param message - The human-readable description of the failure
7848
+ * @param options - The optional {@link CodedErrorOptions}; `cause` reaches `Error.cause` only when present
6872
7849
  */
6873
- constructor(code: LedgerErrorCode, message: string);
7850
+ constructor(code: LedgerErrorCode, message: string, options?: CodedErrorOptions);
6874
7851
  }
6875
7852
 
6876
7853
  /** Names the machine-readable conditions a `LedgerError` error reports. */
@@ -6883,7 +7860,7 @@ export declare type LedgerErrorCode =
6883
7860
  | 'SHARE'
6884
7861
  /** Reports an invalid capacity or a generation cap that is not a nonnegative safe integer less than capacity. */
6885
7862
  | 'CAPACITY'
6886
- /** Reports a recall limit or an agent limit that is not a nonnegative safe integer. */
7863
+ /** Reports a recall limit that is not a nonnegative safe integer, or an agent limit that is not a positive safe integer. */
6887
7864
  | 'LIMIT'
6888
7865
  /** Reports a topic with an empty name or a name another topic carries. */
6889
7866
  | 'TOPIC'
@@ -6894,7 +7871,30 @@ export declare type LedgerErrorCode =
6894
7871
  /** Reports a render context that holds no reference for a source it annotates. */
6895
7872
  | 'REFERENCE'
6896
7873
  /** Reports a snapshot that is malformed or that marks an id its conversation does not hold. */
6897
- | 'SNAPSHOT';
7874
+ | 'SNAPSHOT'
7875
+ /** Reports filing wording that `isLedgerQuestion` refuses. */
7876
+ | 'QUESTION';
7877
+
7878
+ /** Captures held message identities and the accepted edges used to validate their copies. */
7879
+ export declare interface LedgerEvidence {
7880
+ readonly messages: ReadonlySet<string>;
7881
+ readonly amendments: ReadonlyMap<string, LedgerAmendment>;
7882
+ }
7883
+
7884
+ /** Carries a completed request copy, its stored reply, and the sentences the copy rendered. */
7885
+ export declare interface LedgerExchange {
7886
+ readonly request: Message;
7887
+ readonly reply: Message;
7888
+ readonly lines: readonly LedgerOccurrence[];
7889
+ }
7890
+
7891
+ /** Carries the sent request text, stored pair ids, and sentence placements of one exchange. */
7892
+ export declare interface LedgerExchangeSnapshot {
7893
+ readonly request: string;
7894
+ readonly copy?: string;
7895
+ readonly reply: string;
7896
+ readonly lines: readonly LedgerReceipt[];
7897
+ }
6898
7898
 
6899
7899
  /**
6900
7900
  * Carries the price of a prompt in tokens, measured against the model the ledger serves.
@@ -6967,14 +7967,15 @@ export declare interface LedgerInterface {
6967
7967
  * rejects with an `AgentError` whose `code` is `'CONCURRENCY'`. A calibration call that reports no prompt usage, or a prompt usage of 0 or less, rejects with
6968
7968
  * `LedgerError` code `'GAUGE'`; a provider error during calibration rejects with that error.
6969
7969
  * A direct agent run on `conversation` while a `respond` call's pass runs is refused with an
6970
- * `AgentError` whose `code` is `'CONCURRENCY'`; during the calibration that opens the call it is a
6971
- * run no active `respond` call owns. The ledger's agent serves only `conversation`: a run on
6972
- * another conversation started during a `respond` call gets no ledger selection, yet adds its
6973
- * turns and usage to that call's gauge readings and shares its repeat stop, and it can still
6974
- * reach the `recall` and lookup tools, which read `conversation`. The ledger's own guard refuses
6975
- * only `respond`, `calibrate`, and `snapshot` calls.
6976
- * A run no `respond` call owns, including a run during calibration, reads no request's state:
6977
- * its lookup and `recall` calls run with no repeat stop, recall limit, or close rule.
7970
+ * `AgentError` whose `code` is `'CONCURRENCY'`. Under the default `strict`, any other run no active
7971
+ * `respond` call owns rejects with a `LedgerError` whose `code` is `'REQUEST'`: a direct run between
7972
+ * requests, one during calibration, and a run on another conversation during a call. Under
7973
+ * `strict: false` that run goes on over the whole view with no ledger selection; a run on another
7974
+ * conversation then adds its turns and usage to that call's gauge readings and shares its repeat
7975
+ * stop, and it can still reach the `recall` and lookup tools, which read `conversation`. The
7976
+ * ledger's own guard refuses only `respond`, `calibrate`, and `snapshot` calls.
7977
+ * Under `strict: false`, a run no `respond` call owns, including a run during calibration, reads no
7978
+ * request's state: its lookup and `recall` calls run with no repeat stop, recall limit, or close rule.
6978
7979
  * Every rejection leaves the ledger free for a later call.
6979
7980
  *
6980
7981
  * @param content - The request text
@@ -7114,6 +8115,10 @@ export declare interface LedgerNote {
7114
8115
  readonly closure: string;
7115
8116
  }
7116
8117
 
8118
+ /** Carries a rendered sentence with its record placement. */
8119
+ export declare interface LedgerOccurrence extends LedgerLine, LedgerReceipt {
8120
+ }
8121
+
7117
8122
  /**
7118
8123
  * Configures a ledger: its judge and the wording and cutoffs it files with, the desk topics, the
7119
8124
  * context capacity, and the optional first-pass thinking, lookups, gauge, shares, snapshot, recall
@@ -7244,6 +8249,14 @@ export declare interface LedgerRecallOptions {
7244
8249
  readonly limit?: number;
7245
8250
  }
7246
8251
 
8252
+ /** Identifies an original sentence at one record placement. */
8253
+ export declare interface LedgerReceipt {
8254
+ readonly key: string;
8255
+ readonly title: string;
8256
+ readonly source: string;
8257
+ readonly sentence: number;
8258
+ }
8259
+
7247
8260
  /**
7248
8261
  * Carries one record: the live messages placed on one owner or on the rules, as lines.
7249
8262
  *
@@ -7291,6 +8304,12 @@ export declare interface LedgerRenderContext {
7291
8304
  readonly references: ReadonlyMap<string, string>;
7292
8305
  }
7293
8306
 
8307
+ /** Carries rendered record text and its sentences in emission order. */
8308
+ export declare interface LedgerRenderResult {
8309
+ readonly text: string;
8310
+ readonly lines: readonly LedgerOccurrence[];
8311
+ }
8312
+
7294
8313
  /**
7295
8314
  * Holds what one ledger request keeps while it is served: its message, its filing attempts and
7296
8315
  * plan, the gauge calls of its passes, and its repeat and recall stops.
@@ -7332,6 +8351,10 @@ export declare class LedgerRequest implements LedgerRequestInterface {
7332
8351
  * @returns The planned selection, or undefined before one
7333
8352
  */
7334
8353
  get plan(): Selection | undefined;
8354
+ get scope(): ScopeInterface | undefined;
8355
+ apply(scope: ScopeInterface): void;
8356
+ /** Returns the copy and receipts adopted by the last provider turn. */
8357
+ get sent(): LedgerDraft | undefined;
7335
8358
  /**
7336
8359
  * Returns the selection the current pass's run adopted last.
7337
8360
  *
@@ -7368,7 +8391,9 @@ export declare class LedgerRequest implements LedgerRequestInterface {
7368
8391
  observe(call: GaugeCall, position: number): void;
7369
8392
  spend(usage: TokenUsage): void;
7370
8393
  think(messages: readonly Message[]): void;
7371
- file(attempts: readonly ClassifierAttempt[], plan?: Selection): void;
8394
+ fault(error: unknown): void;
8395
+ faulted(error: unknown): boolean;
8396
+ file(attempts: readonly ClassifierAttempt[], plan?: Selection, draft?: LedgerDraft): void;
7372
8397
  admit(name: string, args: Readonly<Record<string, unknown>>): void;
7373
8398
  recall(): void;
7374
8399
  close(): void;
@@ -7389,6 +8414,21 @@ export declare class LedgerRequest implements LedgerRequestInterface {
7389
8414
  * thinking, until its pass observes the next call, and is final from then on.
7390
8415
  */
7391
8416
  export declare interface LedgerRequestInterface {
8417
+ /** Holds the scope last applied by the ledger's plan, or undefined before one. */
8418
+ readonly scope: ScopeInterface | undefined;
8419
+ /** Records the scope applied by the ledger's plan for conditional restoration at settle. */
8420
+ apply(scope: ScopeInterface): void;
8421
+ /** Holds the copy and receipts adopted by the last provider turn, or undefined for a view fallback. */
8422
+ readonly sent: LedgerDraft | undefined;
8423
+ /** Records an error the request's run reported through its `fault` event. */
8424
+ fault(error: unknown): void;
8425
+ /**
8426
+ * Reports whether the request's run reported this error through its `fault` event.
8427
+ *
8428
+ * @param error - The value a pass rejected with
8429
+ * @returns True if the run reported it; false otherwise
8430
+ */
8431
+ faulted(error: unknown): boolean;
7392
8432
  /** Holds the request message, or undefined until `enter` appends it. */
7393
8433
  readonly message: Message | undefined;
7394
8434
  /** Holds the selection the request's last successful plan produced, or undefined before one. */
@@ -7452,8 +8492,9 @@ export declare interface LedgerRequestInterface {
7452
8492
  *
7453
8493
  * @param attempts - The selection's filing attempts, in asking order
7454
8494
  * @param plan - The planned selection, or undefined when planning failed
8495
+ * @param draft - The copy and receipts eligible for adoption; omission discards that eligibility
7455
8496
  */
7456
- file(attempts: readonly ClassifierAttempt[], plan?: Selection): void;
8497
+ file(attempts: readonly ClassifierAttempt[], plan?: Selection, draft?: LedgerDraft): void;
7457
8498
  /**
7458
8499
  * Admits one tool call of the request, compared by tool name and canonical arguments.
7459
8500
  *
@@ -7510,7 +8551,11 @@ export declare interface LedgerResult extends AgentResult {
7510
8551
  *
7511
8552
  * @remarks
7512
8553
  * `prompt` is a share of the ledger's `capacity`; the overhead tokens of the gauge come out of it
7513
- * before the records and the tail take the rest. `tail` is a share of what remains for messages.
8554
+ * before the records and the tail take the rest. `tail` bounds only the seed tail. The seed and
8555
+ * records are planned before the completed-exchange window spends spare room. The full window
8556
+ * with a delta copy, then its newest plain exchange with a full copy, then no exchange are priced
8557
+ * in that order. Admission cannot close an otherwise open recall or displace a selected record
8558
+ * line or seed message. A seed stub reads visibility across the window and the copy together.
7514
8559
  * Each share must be finite, greater than 0, and at most 1.
7515
8560
  */
7516
8561
  export declare interface LedgerShare {
@@ -7528,9 +8573,16 @@ export declare interface LedgerShare {
7528
8573
  * of `conversation.messages`: a request or note a `user` message and a failure a `tool` message.
7529
8574
  * `gauge` carries the scale and overhead alone. The gauge's observations of earlier requests are
7530
8575
  * not carried, so a hydrated ledger sizes and closes `recall` from its fallback reserve until it
7531
- * completes a request. A question the classifier held after a deterministic judge failure is not
7532
- * carried, so a hydrated ledger asks it again. Hydrating a second ledger from one snapshot forks
7533
- * it at the parent's frontier.
8576
+ * completes a request. A question a `strict: false` classifier held after a deterministic judge
8577
+ * failure is not carried, so a hydrated ledger asks it again. Hydrating a second ledger from one snapshot forks
8578
+ * it at the parent's frontier. `window`, when present, retains sent request copies, reply ids,
8579
+ * sentence receipts, and accepted amendment edges. The next plan keeps the same conversation
8580
+ * prefix when the live and hydrated reserves admit the same exchange rung. A rung between those
8581
+ * reserves can differ because hydration carries no gauge observations; this moves the prefix,
8582
+ * never the record coverage. A plain request omits `copy` because its content already lives in `conversation`.
8583
+ * The required window `digest` checks canonical held messages, lookup call context, copies, and receipts. A mismatch drains
8584
+ * the window and its evidence; a missing digest refuses the snapshot. An unencodable held message
8585
+ * makes `snapshot()` omit the window. The checksum detects edits, not authenticity.
7534
8586
  */
7535
8587
  export declare interface LedgerSnapshot {
7536
8588
  readonly conversation: ConversationSnapshot;
@@ -7538,8 +8590,328 @@ export declare interface LedgerSnapshot {
7538
8590
  readonly notes: readonly string[];
7539
8591
  readonly failures: readonly string[];
7540
8592
  readonly gauge?: LedgerGauge;
8593
+ readonly window?: LedgerWindowSnapshot;
7541
8594
  }
7542
8595
 
8596
+ /** Reads structural faults of a ledger snapshot, including its optional held exchange window. */
8597
+ export declare const ledgerSnapshotContract: ContractInterface<Readonly<{
8598
+ conversation: Readonly<{
8599
+ id: string;
8600
+ sections: readonly Readonly<{
8601
+ id: string;
8602
+ summary: string;
8603
+ messages: readonly Readonly<{
8604
+ id: string;
8605
+ role: "assistant" | "system" | "tool" | "user";
8606
+ content: string;
8607
+ } & {
8608
+ calls?: readonly Readonly<{
8609
+ id: string;
8610
+ name: string;
8611
+ arguments: {
8612
+ readonly [k: string]: JSONValue;
8613
+ };
8614
+ } & {}>[];
8615
+ call?: string;
8616
+ images?: readonly string[];
8617
+ thinking?: string;
8618
+ }>[];
8619
+ } & {}>[];
8620
+ messages: readonly Readonly<{
8621
+ id: string;
8622
+ role: "assistant" | "system" | "tool" | "user";
8623
+ content: string;
8624
+ } & {
8625
+ calls?: readonly Readonly<{
8626
+ id: string;
8627
+ name: string;
8628
+ arguments: {
8629
+ readonly [k: string]: JSONValue;
8630
+ };
8631
+ } & {}>[];
8632
+ call?: string;
8633
+ images?: readonly string[];
8634
+ thinking?: string;
8635
+ }>[];
8636
+ } & {
8637
+ judgments?: readonly (Readonly<{
8638
+ id: string;
8639
+ question: Readonly<{
8640
+ form: "choice";
8641
+ criteria: {
8642
+ readonly [k: string]: string | readonly JSONValue[] | {
8643
+ readonly [k: string]: JSONValue;
8644
+ } | null;
8645
+ };
8646
+ } & {
8647
+ instructions?: string | readonly JSONValue[] | {
8648
+ readonly [k: string]: JSONValue;
8649
+ };
8650
+ }> | Readonly<{
8651
+ form: "score";
8652
+ criteria: readonly (string | readonly JSONValue[] | {
8653
+ readonly [k: string]: JSONValue;
8654
+ } | null)[];
8655
+ } & {
8656
+ instructions?: string | readonly JSONValue[] | {
8657
+ readonly [k: string]: JSONValue;
8658
+ };
8659
+ }> | Readonly<{
8660
+ form: "noul";
8661
+ } & {
8662
+ instructions?: string | readonly JSONValue[] | {
8663
+ readonly [k: string]: JSONValue;
8664
+ };
8665
+ criteria?: Readonly<{} & {
8666
+ true?: string | readonly JSONValue[] | {
8667
+ readonly [k: string]: JSONValue;
8668
+ };
8669
+ false?: string | readonly JSONValue[] | {
8670
+ readonly [k: string]: JSONValue;
8671
+ };
8672
+ }>;
8673
+ }>;
8674
+ model: string;
8675
+ sources: readonly string[];
8676
+ state: string;
8677
+ time: number;
8678
+ answer: Readonly<{
8679
+ form: "choice";
8680
+ probabilities: {
8681
+ readonly [k: string]: number;
8682
+ };
8683
+ } & {}> | Readonly<{
8684
+ form: "score";
8685
+ probabilities: readonly number[];
8686
+ } & {}> | Readonly<{
8687
+ form: "noul";
8688
+ noul: number;
8689
+ } & {}>;
8690
+ } & {
8691
+ usage?: Readonly<{
8692
+ prompt: number;
8693
+ completion: number;
8694
+ total: number;
8695
+ } & {}>;
8696
+ }> | Readonly<{
8697
+ id: string;
8698
+ question: Readonly<{
8699
+ form: "choice";
8700
+ criteria: {
8701
+ readonly [k: string]: string | readonly JSONValue[] | {
8702
+ readonly [k: string]: JSONValue;
8703
+ } | null;
8704
+ };
8705
+ } & {
8706
+ instructions?: string | readonly JSONValue[] | {
8707
+ readonly [k: string]: JSONValue;
8708
+ };
8709
+ }> | Readonly<{
8710
+ form: "score";
8711
+ criteria: readonly (string | readonly JSONValue[] | {
8712
+ readonly [k: string]: JSONValue;
8713
+ } | null)[];
8714
+ } & {
8715
+ instructions?: string | readonly JSONValue[] | {
8716
+ readonly [k: string]: JSONValue;
8717
+ };
8718
+ }> | Readonly<{
8719
+ form: "noul";
8720
+ } & {
8721
+ instructions?: string | readonly JSONValue[] | {
8722
+ readonly [k: string]: JSONValue;
8723
+ };
8724
+ criteria?: Readonly<{} & {
8725
+ true?: string | readonly JSONValue[] | {
8726
+ readonly [k: string]: JSONValue;
8727
+ };
8728
+ false?: string | readonly JSONValue[] | {
8729
+ readonly [k: string]: JSONValue;
8730
+ };
8731
+ }>;
8732
+ }>;
8733
+ model: string;
8734
+ sources: readonly string[];
8735
+ state: string;
8736
+ time: number;
8737
+ refusal: Readonly<{
8738
+ missing: readonly string[];
8739
+ } & {}>;
8740
+ } & {
8741
+ usage?: Readonly<{
8742
+ prompt: number;
8743
+ completion: number;
8744
+ total: number;
8745
+ } & {}>;
8746
+ }>)[];
8747
+ }>;
8748
+ requests: readonly string[];
8749
+ notes: readonly string[];
8750
+ failures: readonly string[];
8751
+ } & {
8752
+ gauge?: Readonly<{
8753
+ scale: number;
8754
+ overhead: number;
8755
+ } & {}>;
8756
+ window?: Readonly<{
8757
+ digest: string;
8758
+ exchanges: readonly Readonly<{
8759
+ request: string;
8760
+ reply: string;
8761
+ lines: readonly Readonly<{
8762
+ key: string;
8763
+ title: string;
8764
+ source: string;
8765
+ sentence: number;
8766
+ } & {}>[];
8767
+ } & {
8768
+ copy?: string;
8769
+ }>[];
8770
+ amendments: readonly Readonly<{
8771
+ earlier: string;
8772
+ later: string;
8773
+ } & {}>[];
8774
+ } & {}>;
8775
+ }>>;
8776
+
8777
+ /**
8778
+ * Describes a ledger snapshot exactly: an unknown key refuses, so a key a later version adds never reads
8779
+ * as absent.
8780
+ *
8781
+ * @remarks
8782
+ * `isLedgerSnapshot` is the door a hydrate reads, and this shape fills a refusal's faults. What the shape
8783
+ * cannot state, that each marked id names a message of the snapshot's own conversation, is the guard's
8784
+ * alone.
8785
+ */
8786
+ export declare const ledgerSnapshotShape: ObjectShape< {
8787
+ conversation: ObjectShape< {
8788
+ id: StringShape;
8789
+ sections: ArrayShape<ObjectShape< {
8790
+ id: StringShape;
8791
+ summary: StringShape;
8792
+ messages: ArrayShape<ObjectShape< {
8793
+ id: StringShape;
8794
+ role: LiteralShape<readonly ["system", "user", "assistant", "tool"]>;
8795
+ content: StringShape;
8796
+ calls: OptionalShape<ArrayShape<ObjectShape< {
8797
+ id: StringShape;
8798
+ name: StringShape;
8799
+ arguments: ObjectShape<Record<never, never>, JSONShape>;
8800
+ }, boolean | ContractShape>>>;
8801
+ call: OptionalShape<StringShape>;
8802
+ images: OptionalShape<ArrayShape<StringShape>>;
8803
+ thinking: OptionalShape<StringShape>;
8804
+ }, boolean | ContractShape>>;
8805
+ }, boolean | ContractShape>>;
8806
+ messages: ArrayShape<ObjectShape< {
8807
+ id: StringShape;
8808
+ role: LiteralShape<readonly ["system", "user", "assistant", "tool"]>;
8809
+ content: StringShape;
8810
+ calls: OptionalShape<ArrayShape<ObjectShape< {
8811
+ id: StringShape;
8812
+ name: StringShape;
8813
+ arguments: ObjectShape<Record<never, never>, JSONShape>;
8814
+ }, boolean | ContractShape>>>;
8815
+ call: OptionalShape<StringShape>;
8816
+ images: OptionalShape<ArrayShape<StringShape>>;
8817
+ thinking: OptionalShape<StringShape>;
8818
+ }, boolean | ContractShape>>;
8819
+ judgments: OptionalShape<ArrayShape<UnionShape<readonly [ObjectShape< {
8820
+ id: StringShape;
8821
+ question: UnionShape<readonly [ObjectShape< {
8822
+ form: LiteralShape<readonly ["choice"]>;
8823
+ instructions: OptionalShape<UnionShape<readonly [StringShape, ArrayShape<JSONShape>, ObjectShape<Record<never, never>, JSONShape>]>>;
8824
+ criteria: ObjectShape<Record<never, never>, NullableShape<UnionShape<readonly [StringShape, ArrayShape<JSONShape>, ObjectShape<Record<never, never>, JSONShape>]>>>;
8825
+ }, boolean | ContractShape>, ObjectShape< {
8826
+ form: LiteralShape<readonly ["score"]>;
8827
+ instructions: OptionalShape<UnionShape<readonly [StringShape, ArrayShape<JSONShape>, ObjectShape<Record<never, never>, JSONShape>]>>;
8828
+ criteria: ArrayShape<NullableShape<UnionShape<readonly [StringShape, ArrayShape<JSONShape>, ObjectShape<Record<never, never>, JSONShape>]>>>;
8829
+ }, boolean | ContractShape>, ObjectShape< {
8830
+ form: LiteralShape<readonly ["noul"]>;
8831
+ instructions: OptionalShape<UnionShape<readonly [StringShape, ArrayShape<JSONShape>, ObjectShape<Record<never, never>, JSONShape>]>>;
8832
+ criteria: OptionalShape<ObjectShape< {
8833
+ true: OptionalShape<UnionShape<readonly [StringShape, ArrayShape<JSONShape>, ObjectShape<Record<never, never>, JSONShape>]>>;
8834
+ false: OptionalShape<UnionShape<readonly [StringShape, ArrayShape<JSONShape>, ObjectShape<Record<never, never>, JSONShape>]>>;
8835
+ }, boolean | ContractShape>>;
8836
+ }, boolean | ContractShape>]>;
8837
+ model: StringShape;
8838
+ sources: ArrayShape<StringShape>;
8839
+ state: StringShape;
8840
+ time: NumberShape;
8841
+ usage: OptionalShape<ObjectShape< {
8842
+ prompt: NumberShape;
8843
+ completion: NumberShape;
8844
+ total: NumberShape;
8845
+ }, boolean | ContractShape>>;
8846
+ answer: UnionShape<readonly [ObjectShape< {
8847
+ form: LiteralShape<readonly ["choice"]>;
8848
+ probabilities: ObjectShape<Record<never, never>, NumberShape>;
8849
+ }, boolean | ContractShape>, ObjectShape< {
8850
+ form: LiteralShape<readonly ["score"]>;
8851
+ probabilities: ArrayShape<NumberShape>;
8852
+ }, boolean | ContractShape>, ObjectShape< {
8853
+ form: LiteralShape<readonly ["noul"]>;
8854
+ noul: NumberShape;
8855
+ }, boolean | ContractShape>]>;
8856
+ }, boolean | ContractShape>, ObjectShape< {
8857
+ id: StringShape;
8858
+ question: UnionShape<readonly [ObjectShape< {
8859
+ form: LiteralShape<readonly ["choice"]>;
8860
+ instructions: OptionalShape<UnionShape<readonly [StringShape, ArrayShape<JSONShape>, ObjectShape<Record<never, never>, JSONShape>]>>;
8861
+ criteria: ObjectShape<Record<never, never>, NullableShape<UnionShape<readonly [StringShape, ArrayShape<JSONShape>, ObjectShape<Record<never, never>, JSONShape>]>>>;
8862
+ }, boolean | ContractShape>, ObjectShape< {
8863
+ form: LiteralShape<readonly ["score"]>;
8864
+ instructions: OptionalShape<UnionShape<readonly [StringShape, ArrayShape<JSONShape>, ObjectShape<Record<never, never>, JSONShape>]>>;
8865
+ criteria: ArrayShape<NullableShape<UnionShape<readonly [StringShape, ArrayShape<JSONShape>, ObjectShape<Record<never, never>, JSONShape>]>>>;
8866
+ }, boolean | ContractShape>, ObjectShape< {
8867
+ form: LiteralShape<readonly ["noul"]>;
8868
+ instructions: OptionalShape<UnionShape<readonly [StringShape, ArrayShape<JSONShape>, ObjectShape<Record<never, never>, JSONShape>]>>;
8869
+ criteria: OptionalShape<ObjectShape< {
8870
+ true: OptionalShape<UnionShape<readonly [StringShape, ArrayShape<JSONShape>, ObjectShape<Record<never, never>, JSONShape>]>>;
8871
+ false: OptionalShape<UnionShape<readonly [StringShape, ArrayShape<JSONShape>, ObjectShape<Record<never, never>, JSONShape>]>>;
8872
+ }, boolean | ContractShape>>;
8873
+ }, boolean | ContractShape>]>;
8874
+ model: StringShape;
8875
+ sources: ArrayShape<StringShape>;
8876
+ state: StringShape;
8877
+ time: NumberShape;
8878
+ usage: OptionalShape<ObjectShape< {
8879
+ prompt: NumberShape;
8880
+ completion: NumberShape;
8881
+ total: NumberShape;
8882
+ }, boolean | ContractShape>>;
8883
+ refusal: ObjectShape< {
8884
+ missing: ArrayShape<StringShape>;
8885
+ }, boolean | ContractShape>;
8886
+ }, boolean | ContractShape>]>>>;
8887
+ }, boolean | ContractShape>;
8888
+ requests: ArrayShape<StringShape>;
8889
+ notes: ArrayShape<StringShape>;
8890
+ failures: ArrayShape<StringShape>;
8891
+ gauge: OptionalShape<ObjectShape< {
8892
+ scale: NumberShape;
8893
+ overhead: NumberShape;
8894
+ }, boolean | ContractShape>>;
8895
+ window: OptionalShape<ObjectShape< {
8896
+ digest: StringShape;
8897
+ exchanges: ArrayShape<ObjectShape< {
8898
+ request: StringShape;
8899
+ copy: OptionalShape<StringShape>;
8900
+ reply: StringShape;
8901
+ lines: ArrayShape<ObjectShape< {
8902
+ key: StringShape;
8903
+ title: StringShape;
8904
+ source: StringShape;
8905
+ sentence: NumberShape;
8906
+ }, boolean | ContractShape>>;
8907
+ }, boolean | ContractShape>>;
8908
+ amendments: ArrayShape<ObjectShape< {
8909
+ earlier: StringShape;
8910
+ later: StringShape;
8911
+ }, boolean | ContractShape>>;
8912
+ }, boolean | ContractShape>>;
8913
+ }, boolean | ContractShape>;
8914
+
7543
8915
  /**
7544
8916
  * Carries the probability cutoff of each reading the ledger takes from its judge.
7545
8917
  *
@@ -7577,6 +8949,54 @@ export declare interface LedgerTopic {
7577
8949
  readonly requested?: boolean;
7578
8950
  }
7579
8951
 
8952
+ /** Reads structural faults of a serialized exchange window. */
8953
+ export declare const ledgerWindowContract: ContractInterface<Readonly<{
8954
+ digest: string;
8955
+ exchanges: readonly Readonly<{
8956
+ request: string;
8957
+ reply: string;
8958
+ lines: readonly Readonly<{
8959
+ key: string;
8960
+ title: string;
8961
+ source: string;
8962
+ sentence: number;
8963
+ } & {}>[];
8964
+ } & {
8965
+ copy?: string;
8966
+ }>[];
8967
+ amendments: readonly Readonly<{
8968
+ earlier: string;
8969
+ later: string;
8970
+ } & {}>[];
8971
+ } & {}>>;
8972
+
8973
+ /** Describes the minimal serialized evidence of a nonempty exchange window. */
8974
+ export declare const ledgerWindowShape: ObjectShape< {
8975
+ digest: StringShape;
8976
+ exchanges: ArrayShape<ObjectShape< {
8977
+ request: StringShape;
8978
+ copy: OptionalShape<StringShape>;
8979
+ reply: StringShape;
8980
+ lines: ArrayShape<ObjectShape< {
8981
+ key: StringShape;
8982
+ title: StringShape;
8983
+ source: StringShape;
8984
+ sentence: NumberShape;
8985
+ }, boolean | ContractShape>>;
8986
+ }, boolean | ContractShape>>;
8987
+ amendments: ArrayShape<ObjectShape< {
8988
+ earlier: StringShape;
8989
+ later: StringShape;
8990
+ }, boolean | ContractShape>>;
8991
+ }, boolean | ContractShape>;
8992
+
8993
+ /** Carries a nonempty exchange window, its message, copy, and receipt checksum, and its accepted edges. */
8994
+ export declare interface LedgerWindowSnapshot {
8995
+ readonly digest: string;
8996
+ readonly exchanges: readonly LedgerExchangeSnapshot[];
8997
+ readonly amendments: readonly LedgerAmendment[];
8998
+ }
8999
+
7580
9000
  /** Carries the lowercase words and non-opening capitalized names of a message. */
7581
9001
  export declare interface LedgerWordSet {
7582
9002
  readonly words: ReadonlySet<string>;
@@ -7702,6 +9122,18 @@ export declare function matchesJSON(left: unknown, right: unknown): boolean;
7702
9122
  */
7703
9123
  export declare function matchesJudgment(judgment: Judgment, question: JudgeQuestion, sources: readonly string[], state: string, model: string): boolean;
7704
9124
 
9125
+ /**
9126
+ * Checks whether two successful findings carry the same text for the same canonical lookup.
9127
+ * @param left - The finding to compare
9128
+ * @param right - The candidate copy
9129
+ * @returns True for the same finding or equal canonical identities and text; unkeyable findings match only themselves
9130
+ * @example
9131
+ * ```ts
9132
+ * matchesLookup(finding, finding) // true when it has a result
9133
+ * ```
9134
+ */
9135
+ export declare function matchesLookup(left: LedgerLookupFinding, right: LedgerLookupFinding): boolean;
9136
+
7705
9137
  /**
7706
9138
  * Bounds the decoded error excerpt's input in bytes — `2048`, the leading bytes of a non-OK
7707
9139
  * response body handed to the decoder before the read cancels the remainder, so a `ProviderError`
@@ -7821,6 +9253,21 @@ export declare interface Memo {
7821
9253
  */
7822
9254
  export declare const MEMO_SECTION_HEADER = "## Memos";
7823
9255
 
9256
+ /** Reads the faults of a refused memo revision. */
9257
+ export declare const memoContract: ContractInterface<Readonly<{
9258
+ id: string;
9259
+ name: string;
9260
+ description: string;
9261
+ content: string;
9262
+ time: number;
9263
+ } & {
9264
+ origin?: Readonly<{
9265
+ conversation: string;
9266
+ } & {
9267
+ message?: string;
9268
+ }>;
9269
+ }>>;
9270
+
7824
9271
  /**
7825
9272
  * Carries the data to author a {@link Memo} revision; the {@link MemoManagerInterface} that
7826
9273
  * stores it mints the `id` and records the `time`.
@@ -8154,6 +9601,19 @@ export declare class MemoryMemoStore implements MemoStoreInterface {
8154
9601
  delete(id: string): Promise<void>;
8155
9602
  }
8156
9603
 
9604
+ /** Describes a stored memo revision exactly. */
9605
+ export declare const memoShape: ObjectShape< {
9606
+ id: StringShape;
9607
+ name: StringShape;
9608
+ description: StringShape;
9609
+ content: StringShape;
9610
+ time: NumberShape;
9611
+ origin: OptionalShape<ObjectShape< {
9612
+ conversation: StringShape;
9613
+ message: OptionalShape<StringShape>;
9614
+ }, boolean | ContractShape>>;
9615
+ }, boolean | ContractShape>;
9616
+
8157
9617
  /**
8158
9618
  * Holds every revision of a memo set, oldest first; the current memo of a name is its last
8159
9619
  * revision.
@@ -8170,6 +9630,24 @@ export declare interface MemoSnapshot {
8170
9630
  readonly memos: readonly Memo[];
8171
9631
  }
8172
9632
 
9633
+ /** Reads the faults of a refused memo snapshot. */
9634
+ export declare const memoSnapshotContract: ContractInterface<Readonly<{
9635
+ id: string;
9636
+ memos: readonly Readonly<{
9637
+ id: string;
9638
+ name: string;
9639
+ description: string;
9640
+ content: string;
9641
+ time: number;
9642
+ } & {
9643
+ origin?: Readonly<{
9644
+ conversation: string;
9645
+ } & {
9646
+ message?: string;
9647
+ }>;
9648
+ }>[];
9649
+ } & {}>>;
9650
+
8173
9651
  /**
8174
9652
  * Represents one row of the table a {@link
8175
9653
  * import('./stores/DatabaseMemoStore.js').DatabaseMemoStore} persists — a memo set `id` plus its
@@ -8187,6 +9665,28 @@ export declare interface MemoSnapshotRow {
8187
9665
  readonly snapshot: unknown;
8188
9666
  }
8189
9667
 
9668
+ /**
9669
+ * Describes a stored memo set exactly: an unknown key refuses.
9670
+ *
9671
+ * @remarks
9672
+ * `isMemoSnapshot` is the door a hydrate and a store read, and this shape fills a refusal's faults. A
9673
+ * lockstep test holds that `is` implies the guard, and on the snapshot fixtures the converse.
9674
+ */
9675
+ export declare const memoSnapshotShape: ObjectShape< {
9676
+ id: StringShape;
9677
+ memos: ArrayShape<ObjectShape< {
9678
+ id: StringShape;
9679
+ name: StringShape;
9680
+ description: StringShape;
9681
+ content: StringShape;
9682
+ time: NumberShape;
9683
+ origin: OptionalShape<ObjectShape< {
9684
+ conversation: StringShape;
9685
+ message: OptionalShape<StringShape>;
9686
+ }, boolean | ContractShape>>;
9687
+ }, boolean | ContractShape>>;
9688
+ }, boolean | ContractShape>;
9689
+
8190
9690
  /**
8191
9691
  * Persists a {@link MemoSnapshot} by its memo set id — the async `get` / `set` / `delete`
8192
9692
  * primitives, holding no expiry, the memo twin of {@link
@@ -8330,6 +9830,45 @@ export declare interface MessageInput {
8330
9830
  readonly thinking?: string;
8331
9831
  }
8332
9832
 
9833
+ /** Reads the faults of a refused message input and validates a job's seed messages. */
9834
+ export declare const messageInputContract: ContractInterface<Readonly<{
9835
+ role: "assistant" | "system" | "tool" | "user";
9836
+ content: string;
9837
+ } & {
9838
+ calls?: readonly Readonly<{
9839
+ id: string;
9840
+ name: string;
9841
+ arguments: {
9842
+ readonly [k: string]: JSONValue;
9843
+ };
9844
+ } & {}>[];
9845
+ call?: string;
9846
+ images?: readonly string[];
9847
+ thinking?: string;
9848
+ }>>;
9849
+
9850
+ /**
9851
+ * Describes a message input's JSON projection: a {@link messageShape} with no `id`, which the
9852
+ * storing conversation mints.
9853
+ *
9854
+ * @remarks
9855
+ * A conversation's `add` checks a hoisted hand guard on every message and reads this shape's `audit`
9856
+ * only to fill a refusal's faults. A job's seed messages cross it at `build`. The role literal admits
9857
+ * `system`, so the conversation's `ROLE` refusal explains that case.
9858
+ */
9859
+ export declare const messageInputShape: ObjectShape< {
9860
+ role: LiteralShape<readonly ["system", "user", "assistant", "tool"]>;
9861
+ content: StringShape;
9862
+ calls: OptionalShape<ArrayShape<ObjectShape< {
9863
+ id: StringShape;
9864
+ name: StringShape;
9865
+ arguments: ObjectShape<Record<never, never>, JSONShape>;
9866
+ }, boolean | ContractShape>>>;
9867
+ call: OptionalShape<StringShape>;
9868
+ images: OptionalShape<ArrayShape<StringShape>>;
9869
+ thinking: OptionalShape<StringShape>;
9870
+ }, boolean | ContractShape>;
9871
+
8333
9872
  /**
8334
9873
  * Stores immutable {@link Message} records in insertion order and mints each `id` on `add` — the
8335
9874
  * message-store contract every {@link ConversationInterface} satisfies structurally, the
@@ -8576,7 +10115,7 @@ export declare type ProviderDelta = {
8576
10115
  *
8577
10116
  * @remarks
8578
10117
  * The provider base throws this error for a non-OK HTTP response, a missing response
8579
- * body, or a missing settled result when strict assembly is enabled, and with code `'PROTOCOL'`
10118
+ * body, a stream that ended with no settled result and no terminal record, a result or delta the published contract refuses, and with code `'PROTOCOL'`
8580
10119
  * when the framing seam's `parse` or `finish` throws anything but a provider error, with the throw
8581
10120
  * as `cause`. Concrete wire decoders also use it for malformed records and relayed provider
8582
10121
  * failures.
@@ -8587,6 +10126,8 @@ export declare class ProviderError extends Error {
8587
10126
  readonly code: ProviderErrorCode;
8588
10127
  /** Holds the response status for an HTTP failure, or undefined for other codes. */
8589
10128
  readonly status: number | undefined;
10129
+ /** Holds what the refusal found, such as its faults, or undefined when it carries none. */
10130
+ readonly context: Readonly<Record<string, unknown>> | undefined;
8590
10131
  constructor(code: ProviderErrorCode, message: string, options?: ProviderErrorOptions);
8591
10132
  }
8592
10133
 
@@ -8594,7 +10135,7 @@ export declare class ProviderError extends Error {
8594
10135
  export declare type ProviderErrorCode =
8595
10136
  /** Reports a non-OK HTTP response, including a relay request rejected with status 413. */
8596
10137
  'HTTP'
8597
- /** Reports a missing body, malformed wire record, or missing required settled result. */
10138
+ /** Reports a missing body, malformed wire record, a stream that ended with no settled result and no terminal record, or a result or delta the published contract refuses. */
8598
10139
  | 'PROTOCOL'
8599
10140
  /** Reports an upstream provider failure carried by a relay error record. */
8600
10141
  | 'PROVIDER';
@@ -8603,6 +10144,8 @@ export declare type ProviderErrorCode =
8603
10144
  export declare interface ProviderErrorOptions {
8604
10145
  readonly status?: number;
8605
10146
  readonly cause?: unknown;
10147
+ /** Holds the values that locate the failure, such as the `faults` of a refused question. */
10148
+ readonly context?: Readonly<Record<string, unknown>>;
8606
10149
  }
8607
10150
 
8608
10151
  /** Holds the decoded contribution of a wire record to a provider turn. */
@@ -8613,6 +10156,8 @@ export declare interface ProviderIncrement {
8613
10156
  readonly usage?: TokenUsage;
8614
10157
  readonly truncated?: boolean;
8615
10158
  readonly result?: ProviderResult;
10159
+ /** Marks the wire's terminal record, so a strict engine folds every increment into the settled result. */
10160
+ readonly done?: boolean;
8616
10161
  }
8617
10162
 
8618
10163
  /**
@@ -8989,6 +10534,41 @@ export declare function readChunks(body: ReadableStream<Uint8Array>, signal?: Ab
8989
10534
  */
8990
10535
  export declare function readFailure(response: Response, prefix: string, signal: AbortSignal): Promise<FailureRead>;
8991
10536
 
10537
+ /**
10538
+ * Reads what a judge result holds for one question, from its own keys alone.
10539
+ *
10540
+ * @param result - The reported answers and refusals
10541
+ * @param id - The question's id
10542
+ * @returns The answer and the refusal, each undefined when the result holds none
10543
+ * @example
10544
+ * ```ts
10545
+ * readJudgeOutcome({ model: 'm', answers: {} }, 'q') // { answer: undefined, refusal: undefined }
10546
+ * ```
10547
+ */
10548
+ export declare function readJudgeOutcome(result: JudgeResult, id: string): {
10549
+ readonly answer: JudgeAnswer | undefined;
10550
+ readonly refusal: Refusal | undefined;
10551
+ };
10552
+
10553
+ /**
10554
+ * Reads a foreign delta's two members once into an owned copy, the value a run checks and consumes.
10555
+ *
10556
+ * @remarks
10557
+ * A stream checks every delta, so this is a hand read rather than a record guard. Reading each member
10558
+ * once means a getter can't pass the check with one value and hand the run another. Unknown members
10559
+ * and a class instance pass, and an unreadable member reads as no delta.
10560
+ *
10561
+ * @param value - The value the stream yielded
10562
+ * @returns The owned delta, or undefined when the value is not one
10563
+ *
10564
+ * @example
10565
+ * ```ts
10566
+ * readProviderDelta({ channel: 'content', text: 'Hi' }) // { channel: 'content', text: 'Hi' }
10567
+ * readProviderDelta({ channel: 'audio', text: 'Hi' }) // undefined
10568
+ * ```
10569
+ */
10570
+ export declare function readProviderDelta(value: unknown): ProviderDelta | undefined;
10571
+
8992
10572
  /** Reports a question a wire could not read a candidate for; it lists the caller's keys and invents no probability. */
8993
10573
  export declare interface Refusal {
8994
10574
  readonly missing: readonly string[];
@@ -9581,26 +11161,27 @@ export declare function renderSection<T>(open: string, members: readonly T[], re
9581
11161
  export declare function renderStub(name: string, args: Readonly<Record<string, unknown>>, state: LedgerLookupState): string;
9582
11162
 
9583
11163
  /**
9584
- * Renders a tool's output as the string content of its tool message.
11164
+ * Renders a tool's output as the string content of its tool message, or returns `undefined` when JSON
11165
+ * cannot carry it.
9585
11166
  *
9586
11167
  * @remarks
9587
11168
  * A string passes through unchanged and `undefined` renders as `''`. Any other value renders as
9588
11169
  * its `JSON.stringify` text, byte for byte, when JSON can carry it. A value JSON cannot carry (a
9589
- * `BigInt`, a cycle, a symbol, a throwing `toJSON`) renders as `String(value)`, and as `''` when
9590
- * that conversion throws too, so a tool's output never rejects the run that dispatched it.
11170
+ * `BigInt`, a cycle, a symbol, a function, a throwing `toJSON`) returns `undefined`, which
11171
+ * {@link settleToolResult} turns into a tool failure.
9591
11172
  *
9592
11173
  * @param value - The tool's output (`ToolSuccess.value`, which may be `undefined`)
9593
- * @returns The message content
11174
+ * @returns The message content, or `undefined` when JSON cannot carry the value
9594
11175
  *
9595
11176
  * @example
9596
11177
  * ```ts
9597
11178
  * renderToolValue('sunny') // 'sunny'
9598
11179
  * renderToolValue({ count: 2 }) // '{"count":2}'
9599
11180
  * renderToolValue(undefined) // ''
9600
- * renderToolValue(10n) // '10'
11181
+ * renderToolValue(10n) // undefined
9601
11182
  * ```
9602
11183
  */
9603
- export declare function renderToolValue(value: unknown): string;
11184
+ export declare function renderToolValue(value: unknown): string | undefined;
9604
11185
 
9605
11186
  /**
9606
11187
  * Renders topic names as a comma-separated list in their supplied order.
@@ -9652,6 +11233,28 @@ export declare interface RequestMeasure {
9652
11233
  */
9653
11234
  export declare function requestToRelay(request: ProviderRequest): ProviderRequest;
9654
11235
 
11236
+ /**
11237
+ * Checks a run's final answer against its schema: the content must parse as JSON and satisfy the
11238
+ * schema, or the call throws a coded error carrying the faults.
11239
+ *
11240
+ * @remarks
11241
+ * The schema enters through the lenient `schemaToShape`, which widens every keyword it cannot express
11242
+ * and never narrows, because a provider constrains its own output and a false refusal would discard a
11243
+ * good answer. The check is `is`, because `explain` alone passes what `parse` would repair. Each call
11244
+ * compiles once, and a run has one final answer.
11245
+ *
11246
+ * @param content - The final answer's text
11247
+ * @param schema - The run's JSON Schema
11248
+ * @throws {AgentError} Thrown when the content is not JSON, misses the schema, or the schema does not compile (code `'SCHEMA'`), with the faults under `context.faults` for the first two
11249
+ *
11250
+ * @example
11251
+ * ```ts
11252
+ * requireAnswer('{"a":5}', { type: 'object', properties: { a: { type: 'number' } } })
11253
+ * requireAnswer('nope', { type: 'object' }) // throws AgentError ('SCHEMA')
11254
+ * ```
11255
+ */
11256
+ export declare function requireAnswer(content: string, schema: Readonly<Record<string, unknown>>): void;
11257
+
9655
11258
  /**
9656
11259
  * Returns a run's budget or allowance after checking it implements `BudgetInterface`, or throws a
9657
11260
  * coded error before the run starts it.
@@ -9700,28 +11303,29 @@ export declare function requireConversation(value: unknown): ConversationInterfa
9700
11303
  * throws a coded error.
9701
11304
  *
9702
11305
  * @remarks
9703
- * The check reads `id`, `sections`, `messages`, and `judgments` from `value` once each and builds
9704
- * a candidate from those reads: each array member becomes a fresh array holding the same element
9705
- * objects, and a member that is not an array stays as read, so the guard refuses it. The candidate
9706
- * must pass `isConversationSnapshot`, every section message and live message must play a
9707
- * `ConversationRole`, and no id may repeat across section ids, section message ids, and live
11306
+ * The check reads every own member of `value` once and builds a candidate from those reads: each
11307
+ * array member becomes a fresh array holding the same element objects, and a member that is not an
11308
+ * array stays as read, so the guard refuses it. The candidate must pass `isConversationSnapshot`, which
11309
+ * is exact, so an unknown key refuses rather than being dropped; every section message and live message
11310
+ * must play a `ConversationRole`; and no id may repeat across section ids, section message ids, and live
9708
11311
  * message ids. The `'ROLE'` refusal of a `system` message names the row a snapshot written before
9709
11312
  * 0.0.35 can hold, and each `'SNAPSHOT'` refusal asks for what `snapshot()` returned. The candidate
9710
11313
  * is returned, never `value`, so the check and the seating share one read. Element objects are kept
9711
11314
  * by reference, so a host is trusted not to edit a seated message object or to back its members
9712
- * with accessors.
11315
+ * with accessors. The contract's `audit` runs only after the guard refused, to fill `context.faults`.
9713
11316
  *
9714
11317
  * @param value - The snapshot to check, typically a stored read
9715
- * @returns The candidate snapshot, holding `id`, `sections`, `messages`, and `judgments` when present
9716
- * @throws ConversationError Thrown when the value fails `isConversationSnapshot` or repeats an id (code `'SNAPSHOT'`), or holds a message whose role is not a `ConversationRole` (code `'ROLE'`)
11318
+ * @param contract - The snapshot contract, whose `audit` is read only on a refusal
11319
+ * @returns The candidate snapshot
11320
+ * @throws ConversationError Thrown when the value fails `isConversationSnapshot` (code `'SNAPSHOT'`, its faults under `context.faults`), repeats an id (code `'SNAPSHOT'`), or holds a message whose role is not a `ConversationRole` (code `'ROLE'`)
9717
11321
  *
9718
11322
  * @example
9719
11323
  * ```ts
9720
- * requireConversationSnapshot({ id: 'c1', sections: [], messages: [] }) // { id: 'c1', sections: [], messages: [] }
9721
- * requireConversationSnapshot({ id: 'c1', sections: 'nope', messages: [] }) // throws ConversationError ('SNAPSHOT')
11324
+ * requireConversationSnapshot({ id: 'c1', sections: [], messages: [] }, conversationSnapshotContract) // { id: 'c1', sections: [], messages: [] }
11325
+ * requireConversationSnapshot({ id: 'c1', sections: 'nope', messages: [] }, conversationSnapshotContract) // throws ConversationError ('SNAPSHOT')
9722
11326
  * ```
9723
11327
  */
9724
- export declare function requireConversationSnapshot(value: unknown): ConversationSnapshot;
11328
+ export declare function requireConversationSnapshot(value: unknown, contract: Pick<ContractInterface<unknown>, 'audit' | 'schema'>): ConversationSnapshot;
9725
11329
 
9726
11330
  /**
9727
11331
  * Returns the cumulative switch after checking it does not combine with a `sections` cap, or throws a
@@ -9752,7 +11356,7 @@ export declare function requireCumulative(cumulative: boolean, cap: number | und
9752
11356
  * @param category - The registry category named in an error
9753
11357
  * @param name - The requested key
9754
11358
  * @returns The registered value
9755
- * @throws {AgentError} Thrown when the name is absent, with code REGISTRY and a `context` naming the `category` and the `name`.
11359
+ * @throws {AgentError} Thrown when the name is absent, with code REGISTRY, the name encoded and capped in its text because a tool refusal reaches a model, and a `context` naming the `category` and the `name`.
9756
11360
  * @example
9757
11361
  * ```ts
9758
11362
  * requireEntry(new Map([['main', provider]]), 'provider', 'main') // provider
@@ -9760,6 +11364,47 @@ export declare function requireCumulative(cumulative: boolean, cap: number | und
9760
11364
  */
9761
11365
  export declare function requireEntry<T>(pool: ReadonlyMap<string, T>, category: string, name: string): T;
9762
11366
 
11367
+ /**
11368
+ * Returns an authority's no-match decision after checking the options carry one, or throws a coded
11369
+ * error naming the two fallbacks a host chooses between.
11370
+ *
11371
+ * @remarks
11372
+ * A rules list says nothing about the calls it does not match, so no fallback is assumed: a denylist
11373
+ * and an allowlist differ only here. The check is {@link isAuthorityDecision}, a total guard, so a
11374
+ * missing options object and a malformed fallback refuse alike.
11375
+ *
11376
+ * @param options - The authority's options as a host passed them
11377
+ * @returns The fallback, narrowed to an {@link AuthorityDecision}
11378
+ * @throws {AgentError} Thrown when the options carry no valid `fallback` (code `'AUTHORITY'`)
11379
+ *
11380
+ * @example
11381
+ * ```ts
11382
+ * requireFallback({ fallback: { zone: 'default', verdict: 'deny' } }) // { zone: 'default', verdict: 'deny' }
11383
+ * ```
11384
+ */
11385
+ export declare function requireFallback(options: AuthorityOptions): AuthorityDecision;
11386
+
11387
+ /**
11388
+ * Returns after checking a complete judge result answered or refused every question it was asked, or
11389
+ * throws a coded error naming those it left out.
11390
+ *
11391
+ * @remarks
11392
+ * A cancelled call's partial is not complete, so `JudgmentManager` reads this on a settled result only,
11393
+ * and {@link buildJudgments} stores whatever a partial holds.
11394
+ *
11395
+ * An undefined value is no answer, as {@link buildJudgments} reads it, so a key alone doesn't count.
11396
+ *
11397
+ * @param request - The request whose question keys must be answered
11398
+ * @param result - The result the judge settled
11399
+ * @throws ConversationError Thrown when a question has neither an answer nor a refusal (code `'JUDGMENT'`), naming them under `context.questions`
11400
+ * @example
11401
+ * ```ts
11402
+ * requireJudgeResult({ state: 'text', questions: { a: { form: 'noul' } } }, { model: 'm', answers: {} })
11403
+ * // throws ConversationError ('JUDGMENT')
11404
+ * ```
11405
+ */
11406
+ export declare function requireJudgeResult(request: JudgeRequest, result: JudgeResult): void;
11407
+
9763
11408
  /**
9764
11409
  * Returns a stored judgment record after checking it, or throws a coded error.
9765
11410
  *
@@ -9801,26 +11446,67 @@ export declare function requireJudgment(value: unknown): Judgment;
9801
11446
  export declare function requireKeep(keep: number): number;
9802
11447
 
9803
11448
  /**
9804
- * Returns a tool-iteration cap after checking it is a nonnegative safe integer, or throws a coded
9805
- * error.
11449
+ * Returns a tool-iteration cap after checking it is a positive safe integer, or throws a coded error.
9806
11450
  *
9807
11451
  * @remarks
9808
- * The check is {@link import('../validators.js').isNonNegativeSafeInteger}, so `0` and `-0`
9809
- * pass while `NaN`, a fraction, a negative, and either infinity are refused. The error's `context`
9810
- * carries the refused value as `limit`.
11452
+ * The check is {@link import('../validators.js').isPositiveSafeInteger}, so `0`, `-0`, `NaN`, a
11453
+ * fraction, a negative, and either infinity are refused, because a run of no turns asks the provider
11454
+ * nothing and answers nothing. The error's `context` carries the refused value as `limit`.
9811
11455
  *
9812
11456
  * @param limit - The tool-iteration cap to check
9813
11457
  * @returns The cap unchanged
9814
- * @throws {AgentError} Thrown when `limit` is not a nonnegative safe integer (code `'LIMIT'`)
11458
+ * @throws {AgentError} Thrown when `limit` is not a positive safe integer (code `'LIMIT'`)
9815
11459
  *
9816
11460
  * @example
9817
11461
  * ```ts
9818
11462
  * requireLimit(3) // 3
9819
- * requireLimit(1.5) // throws AgentError ('LIMIT')
11463
+ * requireLimit(0) // throws AgentError ('LIMIT')
9820
11464
  * ```
9821
11465
  */
9822
11466
  export declare function requireLimit(limit: number): number;
9823
11467
 
11468
+ /**
11469
+ * Returns a message input after checking its role and its members, or throws a coded error.
11470
+ *
11471
+ * @remarks
11472
+ * The role goes first, through {@link requireRole}, so its refusal names what it received. The members
11473
+ * cross {@link isMessageInput}, and `audit` runs only after it refused, so a stored message costs one
11474
+ * guard read. Tool-call arguments must also be JSON values before a message is stored.
11475
+ *
11476
+ * @param input - The message input to check
11477
+ * @param contract - The message input contract, whose `audit` is read only on a refusal
11478
+ * @returns The input, narrowed
11479
+ * @throws ConversationError Thrown when the role is not a `ConversationRole` (code `'ROLE'`) or a member fails `isMessageInput` (code `'MESSAGE'`), with the faults under `context.faults`
11480
+ *
11481
+ * @example
11482
+ * ```ts
11483
+ * requireMessageInput({ role: 'user', content: 'hi' }, messageInputContract) // the input
11484
+ * requireMessageInput({ role: 'user' }, messageInputContract) // throws ConversationError ('MESSAGE')
11485
+ * ```
11486
+ */
11487
+ export declare function requireMessageInput(input: unknown, contract: Pick<ContractInterface<unknown>, 'audit' | 'schema'>): MessageInput;
11488
+
11489
+ /**
11490
+ * Owns a provider's settled result: reads each published member of the foreign value once into a fresh
11491
+ * record, checks that copy, and returns it, or throws a coded error the run rejects with.
11492
+ *
11493
+ * @remarks
11494
+ * The check is {@link isProviderResult}, so a class instance carrying the published members passes and
11495
+ * an unknown member is left behind. `usage` is copied count by count; `tools` keeps the array the
11496
+ * provider returned. An absent `usage` stays absent, which the loop bills as its estimate.
11497
+ *
11498
+ * @param value - The value a provider's stream returned
11499
+ * @returns The owned result
11500
+ * @throws {ProviderError} Thrown when the value does not carry the published members (code `PROTOCOL`)
11501
+ *
11502
+ * @example
11503
+ * ```ts
11504
+ * requireProviderResult({ content: 'answer', extra: true }) // { content: 'answer' }
11505
+ * requireProviderResult({}) // throws ProviderError ('PROTOCOL')
11506
+ * ```
11507
+ */
11508
+ export declare function requireProviderResult(value: unknown): ProviderResult;
11509
+
9824
11510
  /**
9825
11511
  * Returns a stored message role after checking it is a conversation role, or throws a coded error.
9826
11512
  *
@@ -9843,15 +11529,34 @@ export declare function requireLimit(limit: number): number;
9843
11529
  export declare function requireRole(role: unknown): ConversationRole;
9844
11530
 
9845
11531
  /**
9846
- * Returns a `sections` cap after checking its lower bound, or throws a coded error.
11532
+ * Returns an authority's rules after checking each one names a verdict, or throws a coded error naming
11533
+ * the first rule that does not.
11534
+ *
11535
+ * @remarks
11536
+ * Absent rules return an empty list. A rule's verdict decides a tool call, so a rule with none is
11537
+ * refused rather than read as an allow. The error's `context` carries the rule's index as `rule`.
11538
+ *
11539
+ * @param rules - The ordered rules, or `undefined` for none
11540
+ * @returns The rules unchanged, or an empty list when none were supplied
11541
+ * @throws {AgentError} Thrown when a rule has no valid `verdict` (code `'AUTHORITY'`)
11542
+ *
11543
+ * @example
11544
+ * ```ts
11545
+ * requireRules([{ match: () => true, zone: 'files', verdict: 'ask' }]).length // 1
11546
+ * ```
11547
+ */
11548
+ export declare function requireRules(rules: readonly AuthorityRule[] | undefined): readonly AuthorityRule[];
11549
+
11550
+ /**
11551
+ * Returns a `sections` cap after checking it is a positive safe integer, or throws a coded error.
9847
11552
  *
9848
11553
  * @remarks
9849
- * A supplied cap must satisfy `>= 1`; fractional caps and positive infinity pass, and `NaN`
9850
- * is refused. An absent cap leaves the sections list unbounded.
11554
+ * A fraction, positive infinity, and `NaN` are refused with `0` and a negative, because a count of
11555
+ * sections is a whole number. An absent cap leaves the sections list unbounded.
9851
11556
  *
9852
11557
  * @param cap - The cap to check, or `undefined` for no cap
9853
11558
  * @returns The cap unchanged, or `undefined` when none was supplied
9854
- * @throws ConversationError Thrown when the cap does not satisfy `>= 1` (code `'SECTIONS'`, including `NaN`)
11559
+ * @throws ConversationError Thrown when the cap is not a positive safe integer (code `'SECTIONS'`)
9855
11560
  *
9856
11561
  * @example
9857
11562
  * ```ts
@@ -9935,7 +11640,8 @@ export declare function sanitizeToken(value: number): number;
9935
11640
  /**
9936
11641
  * Sanitizes a {@link TokenUsage} into non-negative integers — the guard an agent's
9937
11642
  * abort-usage path applies to a provider's partial usage before it is charged against a
9938
- * budget or folded into the run total.
11643
+ * budget or folded into the run total, because a cancelled stream has no settled result to refuse;
11644
+ * a settled result's usage crosses the provider-result door instead.
9939
11645
  *
9940
11646
  * @remarks
9941
11647
  * Per field (`prompt` / `completion` / `total`): a non-finite value (`NaN`, `+Infinity`,
@@ -9965,6 +11671,39 @@ export declare function sanitizeUsage(usage: TokenUsage): TokenUsage;
9965
11671
  */
9966
11672
  export declare function scanAmendments(amendments: ReadonlyMap<string, readonly string[]>, start: string, admit: (id: string) => boolean): readonly string[];
9967
11673
 
11674
+ /**
11675
+ * Scans what a judge's answer must hold to its question: the same form, every probability in
11676
+ * `[0, 1]`, a choice's keys equal to the criteria keys, and a score as long as its levels.
11677
+ *
11678
+ * @remarks
11679
+ * These ties run where a judgment is written, at `JudgmentManager.add` and the `AgentJudge` result
11680
+ * ingestion. A read of a stored record checks only exact keys, literal forms, and number types,
11681
+ * because records written before the ties can miss them.
11682
+ *
11683
+ * @param question - The question that was asked
11684
+ * @param answer - The answer the judge gave
11685
+ * @returns Every broken tie as a fault, or an empty list
11686
+ * @example
11687
+ * ```ts
11688
+ * scanJudgmentTies({ form: 'noul' }, { form: 'noul', noul: 2 })
11689
+ * // [{ reason: 'constraint', path: ['answer', 'noul'], expected: 'number', constraint: 'max', limit: 1, received: '2' }]
11690
+ * ```
11691
+ */
11692
+ export declare function scanJudgmentTies(question: JudgeQuestion, answer: JudgeAnswer): readonly AuditFault[];
11693
+
11694
+ /**
11695
+ * Scans one probability against `[0, 1]`.
11696
+ *
11697
+ * @param value - The probability
11698
+ * @param path - Where it sits
11699
+ * @returns A constraint fault when it is out of bounds, or an empty list
11700
+ * @example
11701
+ * ```ts
11702
+ * scanProbability(0.5, ['answer', 'noul']) // []
11703
+ * ```
11704
+ */
11705
+ export declare function scanProbability(value: number | undefined, path: readonly string[]): readonly AuditFault[];
11706
+
9968
11707
  /**
9969
11708
  * Represents a named, immutable filter over a richer context's items — an optional allow-list per
9970
11709
  * category (`instructions` / `skills` / `memos` / `tools` / `files`), each keyed by that category's
@@ -10252,6 +11991,47 @@ export declare interface Section {
10252
11991
  readonly messages: readonly Message[];
10253
11992
  }
10254
11993
 
11994
+ /** Reads the faults of a refused section. */
11995
+ export declare const sectionContract: ContractInterface<Readonly<{
11996
+ id: string;
11997
+ summary: string;
11998
+ messages: readonly Readonly<{
11999
+ id: string;
12000
+ role: "assistant" | "system" | "tool" | "user";
12001
+ content: string;
12002
+ } & {
12003
+ calls?: readonly Readonly<{
12004
+ id: string;
12005
+ name: string;
12006
+ arguments: {
12007
+ readonly [k: string]: JSONValue;
12008
+ };
12009
+ } & {}>[];
12010
+ call?: string;
12011
+ images?: readonly string[];
12012
+ thinking?: string;
12013
+ }>[];
12014
+ } & {}>>;
12015
+
12016
+ /** Describes a compacted section: its id, its summary, and the originals it folded. */
12017
+ export declare const sectionShape: ObjectShape< {
12018
+ id: StringShape;
12019
+ summary: StringShape;
12020
+ messages: ArrayShape<ObjectShape< {
12021
+ id: StringShape;
12022
+ role: LiteralShape<readonly ["system", "user", "assistant", "tool"]>;
12023
+ content: StringShape;
12024
+ calls: OptionalShape<ArrayShape<ObjectShape< {
12025
+ id: StringShape;
12026
+ name: StringShape;
12027
+ arguments: ObjectShape<Record<never, never>, JSONShape>;
12028
+ }, boolean | ContractShape>>>;
12029
+ call: OptionalShape<StringShape>;
12030
+ images: OptionalShape<ArrayShape<StringShape>>;
12031
+ thinking: OptionalShape<StringShape>;
12032
+ }, boolean | ContractShape>>;
12033
+ }, boolean | ContractShape>;
12034
+
10255
12035
  /**
10256
12036
  * Carries the conversation part of the next prompt and the receipt for it.
10257
12037
  *
@@ -10352,6 +12132,29 @@ export declare function selectRecords(projection: LedgerProjection, request: Led
10352
12132
  */
10353
12133
  export declare function settleAgentJob(agent: AgentInterface, partial: boolean): Promise<AgentResult>;
10354
12134
 
12135
+ /**
12136
+ * Settles one dispatched result into the result the loop reports and the content of its tool message,
12137
+ * turning a success whose value JSON cannot carry into a tool failure the model reads.
12138
+ *
12139
+ * @remarks
12140
+ * A failure passes through with its `error` as the content. A success renders through
12141
+ * {@link renderToolValue}. A success that renders to `undefined` becomes the failure arm with the
12142
+ * call's `id` and `name`, whose `error` names the tool and the remedy.
12143
+ *
12144
+ * @param result - The result the tool manager returned for one call
12145
+ * @returns The result to report and the tool message content
12146
+ *
12147
+ * @example
12148
+ * ```ts
12149
+ * settleToolResult({ success: true, id: '1', name: 'read', value: { count: 2 } }).content // '{"count":2}'
12150
+ * settleToolResult({ success: true, id: '1', name: 'read', value: 10n }).outcome.success // false
12151
+ * ```
12152
+ */
12153
+ export declare function settleToolResult(result: ToolResult): {
12154
+ readonly outcome: ToolResult;
12155
+ readonly content: string;
12156
+ };
12157
+
10355
12158
  /**
10356
12159
  * Holds one skill: a name and a description the index shows, the instructions loading adds, and
10357
12160
  * bundled files.
@@ -10945,7 +12748,7 @@ export declare interface ThinkSplitterInterface {
10945
12748
  * counts, shared by the provider result and the agent frame wires.
10946
12749
  *
10947
12750
  * @remarks
10948
- * The guard refuses extra members; the contract parser drops them.
12751
+ * Each count is a nonnegative number. The guard refuses extra members; the contract parser drops them.
10949
12752
  */
10950
12753
  export declare const tokenUsageShape: ObjectShape< {
10951
12754
  prompt: NumberShape;
@@ -10955,9 +12758,9 @@ total: NumberShape;
10955
12758
 
10956
12759
  /**
10957
12760
  * Projects an unknown value onto a fresh, exact `TokenUsage` — capturing `prompt`, `completion`, and
10958
- * `total` once each through a total boundary, preserving finite negative and fractional counts,
10959
- * dropping extras, and resolving `undefined` for a non-object, a missing or non-finite count, a
10960
- * throwing getter, or a malformed or revoked proxy.
12761
+ * `total` once each through a total boundary, preserving fractional counts, dropping extras, and
12762
+ * resolving `undefined` for a non-object, a missing, negative, or non-finite count, a throwing getter,
12763
+ * or a malformed or revoked proxy.
10961
12764
  *
10962
12765
  * @remarks
10963
12766
  * The capture runs inside Contract's sanctioned exception boundary, so conforming accessors and
@@ -10966,13 +12769,14 @@ total: NumberShape;
10966
12769
  * before it projects, because this function refuses `undefined` like any other non-object.
10967
12770
  *
10968
12771
  * @param value - The unknown value to project
10969
- * @returns A fresh `{ prompt, completion, total }`, or `undefined` when the value is not a finite usage triple
12772
+ * @returns A fresh `{ prompt, completion, total }`, or `undefined` when the value is not a finite nonnegative usage triple
10970
12773
  *
10971
12774
  * @example
10972
12775
  * ```ts
10973
12776
  * import { tokenUsageToJSON } from '@orkestrel/agent'
10974
12777
  *
10975
- * tokenUsageToJSON({ prompt: 2, completion: -1, total: 1.5, cached: 4 }) // { prompt: 2, completion: -1, total: 1.5 }
12778
+ * tokenUsageToJSON({ prompt: 2, completion: 1, total: 1.5, cached: 4 }) // { prompt: 2, completion: 1, total: 1.5 }
12779
+ * tokenUsageToJSON({ prompt: 2, completion: -1, total: 1 }) // undefined
10976
12780
  * tokenUsageToJSON({ prompt: 2, completion: Infinity, total: 3 }) // undefined
10977
12781
  * ```
10978
12782
  */