@full-self-browsing/lattice 0.0.0-bootstrap.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,2359 @@
1
+ import { StandardSchemaV1 } from "@standard-schema/spec";
2
+
3
+ //#region src/policy/policy.d.ts
4
+ interface PolicySpec {
5
+ readonly maxCostUsd?: number;
6
+ readonly latency?: "interactive" | "batch";
7
+ readonly privacy?: "standard" | "sensitive" | "restricted";
8
+ readonly providerAllowList?: readonly string[];
9
+ readonly providerDenyList?: readonly string[];
10
+ readonly noUpload?: boolean;
11
+ readonly noPublicUrl?: boolean;
12
+ readonly noLogging?: boolean;
13
+ readonly metadata?: Record<string, unknown>;
14
+ }
15
+ //#endregion
16
+ //#region src/artifacts/lineage.d.ts
17
+ type ArtifactTransformKind = "manual" | "generated" | "extraction" | "chunking" | "transcription" | "resizing" | "provider-packaging" | "tool-result" | "model-output";
18
+ interface ArtifactTransformDescriptor {
19
+ readonly kind: ArtifactTransformKind;
20
+ readonly name?: string;
21
+ readonly metadata?: Record<string, unknown>;
22
+ }
23
+ interface ArtifactParentRef {
24
+ readonly id: string;
25
+ readonly kind: ArtifactKind;
26
+ readonly mediaType?: string;
27
+ readonly source: ArtifactSource;
28
+ readonly label?: string;
29
+ readonly metadata?: Record<string, unknown>;
30
+ readonly privacy: ArtifactPrivacy;
31
+ readonly size?: ArtifactSize;
32
+ readonly fingerprint?: ArtifactFingerprint;
33
+ readonly storage?: ArtifactStorageRef;
34
+ readonly lineage?: ArtifactLineage;
35
+ }
36
+ interface ArtifactLineage {
37
+ readonly parents: readonly ArtifactParentRef[];
38
+ readonly transform: ArtifactTransformDescriptor;
39
+ }
40
+ //#endregion
41
+ //#region src/artifacts/artifact.d.ts
42
+ type ArtifactKind = "text" | "json" | "file" | "image" | "audio" | "video" | "document" | "url" | "tool-result";
43
+ type ProviderUploadArtifactSource = `provider-${"up"}${"load"}`;
44
+ type ArtifactSource = "inline" | "file" | "url" | "generated" | ProviderUploadArtifactSource | "tool";
45
+ type ArtifactPrivacy = NonNullable<PolicySpec["privacy"]>;
46
+ interface ArtifactSize {
47
+ readonly bytes?: number;
48
+ readonly characters?: number;
49
+ readonly pages?: number;
50
+ readonly width?: number;
51
+ readonly height?: number;
52
+ readonly durationMs?: number;
53
+ }
54
+ interface ArtifactFingerprint {
55
+ readonly algorithm: "sha256";
56
+ readonly value: string;
57
+ }
58
+ interface ArtifactStorageRef {
59
+ readonly storeId: string;
60
+ readonly key: string;
61
+ }
62
+ interface ArtifactOptions {
63
+ readonly id?: string;
64
+ readonly mediaType?: string;
65
+ readonly label?: string;
66
+ readonly metadata?: Record<string, unknown>;
67
+ readonly privacy?: ArtifactPrivacy;
68
+ readonly size?: ArtifactSize;
69
+ readonly fingerprint?: ArtifactFingerprint;
70
+ readonly storage?: ArtifactStorageRef;
71
+ readonly lineage?: ArtifactLineage;
72
+ }
73
+ interface ArtifactToolResultOptions extends ArtifactOptions {
74
+ readonly toolName: string;
75
+ readonly callId?: string;
76
+ }
77
+ interface ArtifactDerivedOptions extends ArtifactOptions {
78
+ readonly kind: ArtifactKind;
79
+ readonly source?: ArtifactSource;
80
+ readonly value?: unknown;
81
+ readonly parents: readonly ArtifactRef[];
82
+ readonly transform: ArtifactTransformDescriptor;
83
+ }
84
+ interface ArtifactRef {
85
+ readonly id: string;
86
+ readonly kind: ArtifactKind;
87
+ readonly mediaType?: string;
88
+ readonly source: ArtifactSource;
89
+ readonly label?: string;
90
+ readonly metadata?: Record<string, unknown>;
91
+ readonly privacy: ArtifactPrivacy;
92
+ readonly size?: ArtifactSize;
93
+ readonly fingerprint?: ArtifactFingerprint;
94
+ readonly storage?: ArtifactStorageRef;
95
+ readonly lineage?: ArtifactLineage;
96
+ }
97
+ type ArtifactInput = ArtifactRef & {
98
+ readonly value?: unknown;
99
+ };
100
+ declare const artifact: {
101
+ text(value: string, options?: ArtifactOptions): ArtifactInput;
102
+ json(value: unknown, options?: ArtifactOptions): ArtifactInput;
103
+ file(value: Blob | File | string, options?: ArtifactOptions): ArtifactInput;
104
+ image(value: Blob | File | string, options?: ArtifactOptions): ArtifactInput;
105
+ audio(value: Blob | File | string, options?: ArtifactOptions): ArtifactInput;
106
+ document(value: Blob | File | string, options?: ArtifactOptions): ArtifactInput;
107
+ url(value: string | URL, options?: ArtifactOptions): ArtifactInput;
108
+ toolResult(value: unknown, options: ArtifactToolResultOptions): ArtifactInput;
109
+ derive(input: ArtifactDerivedOptions): ArtifactInput;
110
+ };
111
+ //#endregion
112
+ //#region src/tracing/tracing.d.ts
113
+ interface TracerLike {
114
+ readonly kind: "tracer";
115
+ readonly span?: <T>(name: string, fn: () => T | Promise<T>, attributes?: Record<string, unknown>) => T | Promise<T>;
116
+ readonly event?: (name: string, attributes?: Record<string, unknown>) => void;
117
+ }
118
+ type RunEventKind = "run.start" | "artifact.ingested" | "context.packed" | "router.candidates" | "stage.start" | "stage.complete" | "provider.attempt" | "fallback.activated" | "validation.complete" | "validation.failed" | "artifact.created" | "run.complete" | "run.failed" | "tool.call" | "replay.offline" | "replay.live" | "step.transition" | "recovery.start" | "recovery.complete" | "recovery.failed";
119
+ interface RunEvent {
120
+ readonly kind: RunEventKind;
121
+ readonly timestamp: string;
122
+ readonly runId: string;
123
+ readonly planId?: string;
124
+ readonly stageId?: string;
125
+ readonly providerId?: string;
126
+ readonly modelId?: string;
127
+ readonly artifactId?: string;
128
+ readonly metadata?: Record<string, unknown>;
129
+ }
130
+ type RunEventSink = (event: RunEvent) => void | Promise<void>;
131
+ //#endregion
132
+ //#region src/contract/bands.d.ts
133
+ /**
134
+ * Hook lifecycle event vocabulary -- separate from RunEventKind by design.
135
+ *
136
+ * Phase 19 (v1.2) additively extends with BEFORE_AGENT_ITERATION and
137
+ * AFTER_AGENT_ITERATION — emitted by `runAgent` around each iteration's
138
+ * provider call. Existing four events continue to fire inside each
139
+ * iteration (BEFORE/AFTER_PROVIDER per native call; BEFORE/AFTER_TOOL
140
+ * per dispatched tool).
141
+ */
142
+ type HookLifecycleEvent = "BEFORE_PROVIDER" | "AFTER_PROVIDER" | "BEFORE_TOOL" | "AFTER_TOOL" | "BEFORE_AGENT_ITERATION" | "AFTER_AGENT_ITERATION";
143
+ /**
144
+ * SAFETY-band veto mechanism — Phase 19.
145
+ *
146
+ * Handlers can deny an iteration by calling `controls.deny(reason)`. The
147
+ * pipeline records the latest reason and exposes it via `lastDenialReason()`.
148
+ * The reason resets at the start of each `run()` call.
149
+ *
150
+ * Composition convention: the agent runtime invokes BEFORE_AGENT_ITERATION
151
+ * before provider call, then checks `pipeline.lastDenialReason()`. If set,
152
+ * the iteration aborts with `agent-iteration-denied` failure.
153
+ */
154
+ interface HookDenyDirective {
155
+ readonly reason: string;
156
+ }
157
+ /**
158
+ * Controls passed to each handler as an optional second argument.
159
+ *
160
+ * Backward compat: existing single-argument handlers (Phase 15 + Phase 16)
161
+ * ignore this and continue to work unchanged.
162
+ */
163
+ interface HookControls {
164
+ /** Set a denial reason; the latest call wins per `run()`. */
165
+ readonly deny: (reason: string) => void;
166
+ }
167
+ /**
168
+ * Priority bands. Lower number = higher priority (runs first).
169
+ *
170
+ * SAFETY (0) -- safety / breaker hooks; cannot be overridden by lower bands
171
+ * OBSERVABILITY (1) -- logging, metrics, audit; runs after safety, before extension
172
+ * EXTENSION (2) -- user-supplied hooks; runs last
173
+ *
174
+ * Within a band, handlers run in registration order.
175
+ */
176
+ declare const BAND: {
177
+ readonly SAFETY: 0;
178
+ readonly OBSERVABILITY: 1;
179
+ readonly EXTENSION: 2;
180
+ };
181
+ type Band = typeof BAND[keyof typeof BAND];
182
+ /**
183
+ * Handler input -- frozen snapshot of the caller's context at run() time.
184
+ *
185
+ * structuredClone-then-Object.freeze: handlers receive a deep-cloned,
186
+ * surface-frozen view. Mutations on the handler side do NOT leak back to
187
+ * the calling site.
188
+ *
189
+ * The handler's return value is currently ignored; future revisions may
190
+ * add a typed return that downstream bands consume.
191
+ */
192
+ interface HookHandler<TContext = unknown> {
193
+ (context: Readonly<TContext>, controls?: HookControls): void | Promise<void>;
194
+ }
195
+ interface RegisterOptions {
196
+ readonly band: Band;
197
+ readonly matcher?: RegExp;
198
+ readonly budgetMs?: number;
199
+ }
200
+ /**
201
+ * The HookPipeline interface returned by createHookPipeline().
202
+ *
203
+ * IMMUTABILITY: once freeze() is called, register() throws an Error whose
204
+ * .name === "PIPELINE_FROZEN". freeze() is irreversible by design --
205
+ * protects against late-binding hook injection mid-session.
206
+ */
207
+ interface HookPipeline {
208
+ readonly kind: "hook-pipeline";
209
+ register<TContext = unknown>(event: HookLifecycleEvent, handler: HookHandler<TContext>, options: RegisterOptions): void;
210
+ freeze(): void;
211
+ isFrozen(): boolean;
212
+ run<TContext = unknown>(event: HookLifecycleEvent, context: TContext): Promise<void>;
213
+ /**
214
+ * Phase 19: returns the latest denial reason set by any handler during
215
+ * the most recent `run()` call. Resets to `null` at the start of each run.
216
+ * Read by the agent runtime to detect SAFETY-band veto.
217
+ */
218
+ lastDenialReason(): string | null;
219
+ }
220
+ interface CreateHookPipelineOptions {
221
+ readonly tracer?: TracerLike;
222
+ readonly sessionId?: string;
223
+ readonly defaultBudgetMs?: number;
224
+ }
225
+ /**
226
+ * Factory: build a fresh hook pipeline.
227
+ */
228
+ declare function createHookPipeline(options?: CreateHookPipelineOptions): HookPipeline;
229
+ //#endregion
230
+ //#region src/contract/invariants.d.ts
231
+ /**
232
+ * Tripwire invariant declaration variants produced by the `inv` fluent
233
+ * builder. Each variant is a frozen value carrying a discriminant `kind`
234
+ * and an `id` (auto-generated or caller-supplied).
235
+ *
236
+ * Phase 8 reshapes the Phase 7 placeholder `{ kind: "policy"|"semantic"|"schema" }`
237
+ * into this discriminated union. Phase 7 never populated `invariants`
238
+ * (see 07-04-SUMMARY decisions), so the change is additive in practice
239
+ * but technically a breaking type change for any external caller that
240
+ * authored a literal of the old shape.
241
+ */
242
+ interface MustCiteInvariant {
243
+ readonly id: string;
244
+ readonly kind: "must-cite";
245
+ readonly artifactName: string;
246
+ }
247
+ interface FieldFromTableInvariant {
248
+ readonly id: string;
249
+ readonly kind: "field-from-table";
250
+ readonly path: string;
251
+ readonly allowedValues: readonly string[];
252
+ }
253
+ interface NoPiiInvariant {
254
+ readonly id: string;
255
+ readonly kind: "no-pii";
256
+ readonly path: string;
257
+ }
258
+ interface MatchesInvariant<T = unknown> {
259
+ readonly id: string;
260
+ readonly kind: "matches";
261
+ readonly path: string;
262
+ readonly schema: StandardSchemaV1<unknown, T>;
263
+ }
264
+ type InvariantDeclaration = MustCiteInvariant | FieldFromTableInvariant | NoPiiInvariant | MatchesInvariant;
265
+ interface InvariantOptions {
266
+ readonly id?: string;
267
+ }
268
+ /**
269
+ * Fluent builder for tripwire invariants.
270
+ *
271
+ * Each helper returns a frozen `InvariantDeclaration` with an auto-generated
272
+ * id of the form `${kind}-${counter}`. Callers may override the id via the
273
+ * second-positional `options.id` arg.
274
+ *
275
+ * The counter is monotonic across kinds — calling `inv.mustCite("a")` then
276
+ * `inv.fieldFromTable("x", ["y"])` yields ids `must-cite-1` then
277
+ * `field-from-table-2`. This keeps ids globally unique within a process.
278
+ *
279
+ * Note on `inv.matches`: the caller supplies the StandardSchema validator,
280
+ * and the tripwire evaluator trusts whatever `~standard.validate` returns.
281
+ * This is by design — `matches` is the caller-driven escape hatch (see
282
+ * T-08-05 in the 08-01-PLAN threat register).
283
+ */
284
+ declare const inv: {
285
+ readonly mustCite: (artifactName: string, options?: InvariantOptions) => MustCiteInvariant;
286
+ readonly fieldFromTable: (path: string, allowedValues: readonly string[], options?: InvariantOptions) => FieldFromTableInvariant;
287
+ readonly noPII: (path: string, options?: InvariantOptions) => NoPiiInvariant;
288
+ readonly matches: <T>(path: string, schema: StandardSchemaV1<unknown, T>, options?: InvariantOptions) => MatchesInvariant<T>;
289
+ /**
290
+ * Test-only: reset the auto-id counter. NOT exported from the package
291
+ * root barrel — callers must import `inv` directly from this module if
292
+ * they ever need it, which is intentional friction.
293
+ */
294
+ readonly __resetCounterForTests: () => void;
295
+ };
296
+ //#endregion
297
+ //#region src/contract/pii-detectors.d.ts
298
+ /**
299
+ * Regex-based PII detectors used by the `no-pii` tripwire invariant.
300
+ *
301
+ * Phase 8 ships four detectors (email, US SSN, Luhn-valid credit card,
302
+ * US phone). They are intentionally regex-only — zero new dependencies —
303
+ * per the v1.1 scope locked in 08-CONTEXT.md.
304
+ *
305
+ * Each detector returns either `{ matched: true, substring }` carrying
306
+ * ONLY the matched fragment, or `{ matched: false }`. The substring shape
307
+ * is required so the tripwire evaluator can emit redacted evidence
308
+ * (Phase 9 receipts must not leak the full input).
309
+ *
310
+ * Detector order in `defaultPiiDetectors` is deterministic so the
311
+ * evaluator's first-violation semantics produce stable receipts.
312
+ */
313
+ type PiiDetectorResult = {
314
+ readonly matched: true;
315
+ readonly substring: string;
316
+ } | {
317
+ readonly matched: false;
318
+ };
319
+ interface PiiDetector {
320
+ readonly name: string;
321
+ detect(input: string): PiiDetectorResult;
322
+ }
323
+ /**
324
+ * Default PII detectors used by `evaluateTripwires` for `no-pii` invariants.
325
+ *
326
+ * Order is deterministic: email, us-ssn, credit-card, us-phone. Callers who
327
+ * need a different set can pass their own list to `evaluateTripwires`.
328
+ */
329
+ declare const defaultPiiDetectors: readonly PiiDetector[];
330
+ //#endregion
331
+ //#region src/contract/tripwire.d.ts
332
+ /**
333
+ * Evidence emitted when a tripwire invariant fires.
334
+ *
335
+ * `observed` is the SHAPE-MATCHED redacted payload, not the raw output:
336
+ * - for `must-cite`: the citations array as found at the located path
337
+ * - for `field-from-table`: the actual value at `path`
338
+ * - for `no-pii`: ONLY `{ detector, substring }` — never the full input
339
+ * (T-08-01 in the 08-01-PLAN threat register)
340
+ * - for `matches`: the value at `path`
341
+ *
342
+ * Phase 9 receipts will sign this evidence, so leaking the full PII into
343
+ * `observed` would defeat redact-before-sign.
344
+ */
345
+ interface TripwireEvidence {
346
+ readonly invariantId: string;
347
+ readonly kind: "must-cite" | "field-from-table" | "no-pii" | "matches";
348
+ readonly path: string;
349
+ readonly observed: unknown;
350
+ readonly message: string;
351
+ }
352
+ type TripwireResult = {
353
+ readonly ok: true;
354
+ } | {
355
+ readonly ok: false;
356
+ readonly evidence: TripwireEvidence;
357
+ };
358
+ /**
359
+ * Pure tripwire evaluator.
360
+ *
361
+ * No I/O, no Date.now, no random — same `(output, invariants)` always
362
+ * returns the same `TripwireResult`. Phase 9 receipts can reconstruct the
363
+ * verdict deterministically (T-08-04).
364
+ *
365
+ * Evaluates invariants in declaration order; the FIRST failing invariant
366
+ * aborts and returns its evidence. Subsequent invariants are not evaluated.
367
+ *
368
+ * @param output The provider output to inspect.
369
+ * @param invariants Invariants to evaluate, in declaration order.
370
+ * @param detectors PII detectors used for `no-pii` invariants. Defaults
371
+ * to `defaultPiiDetectors`. Callers can pass a custom
372
+ * list to override.
373
+ */
374
+ declare function evaluateTripwires(output: unknown, invariants: readonly InvariantDeclaration[], detectors?: readonly PiiDetector[]): Promise<TripwireResult>;
375
+ //#endregion
376
+ //#region src/outputs/contracts.d.ts
377
+ type TextOutputContract = "text";
378
+ interface CitationRef {
379
+ readonly artifactId: string;
380
+ readonly label?: string;
381
+ readonly span?: {
382
+ readonly start?: number;
383
+ readonly end?: number;
384
+ };
385
+ readonly metadata?: Record<string, unknown>;
386
+ }
387
+ interface CitationsOutputContract {
388
+ readonly kind: "citations";
389
+ }
390
+ interface ArtifactRefsOutputContract {
391
+ readonly kind: "artifacts";
392
+ readonly artifactKind?: ArtifactKind | string;
393
+ }
394
+ type SchemaOutputContract = StandardSchemaV1;
395
+ type OutputContract = TextOutputContract | SchemaOutputContract | CitationsOutputContract | ArtifactRefsOutputContract;
396
+ type OutputContractMap = Record<string, OutputContract>;
397
+ declare const output: {
398
+ citations(): CitationsOutputContract;
399
+ artifacts(options?: {
400
+ readonly artifactKind?: ArtifactKind | string;
401
+ }): ArtifactRefsOutputContract;
402
+ };
403
+ //#endregion
404
+ //#region src/sessions/session.d.ts
405
+ interface SessionRef {
406
+ readonly id: string;
407
+ readonly kind?: "session-ref";
408
+ }
409
+ interface SessionTurn {
410
+ readonly id: string;
411
+ readonly task: string;
412
+ readonly artifactRefs: readonly ArtifactRef[];
413
+ readonly planId?: string;
414
+ readonly outputArtifactRefs: readonly ArtifactRef[];
415
+ readonly createdAt: string;
416
+ }
417
+ interface SessionSummary {
418
+ readonly id: string;
419
+ readonly artifactRef: ArtifactRef;
420
+ readonly sourceTurnIds: readonly string[];
421
+ readonly trust: "model-summary";
422
+ readonly createdAt: string;
423
+ }
424
+ interface SessionRecord extends SessionRef {
425
+ readonly kind: "session-ref";
426
+ readonly parentId?: string;
427
+ readonly branchPointRunId?: string;
428
+ readonly turns: readonly SessionTurn[];
429
+ readonly summaries: readonly SessionSummary[];
430
+ readonly artifactRefs: readonly ArtifactRef[];
431
+ readonly planIds: readonly string[];
432
+ readonly createdAt: string;
433
+ readonly updatedAt: string;
434
+ }
435
+ interface CreateSessionOptions {
436
+ readonly id?: string;
437
+ readonly parentId?: string;
438
+ readonly branchPointRunId?: string;
439
+ }
440
+ interface AppendSessionTurnInput {
441
+ readonly sessionId: string;
442
+ readonly task: string;
443
+ readonly artifactRefs: readonly ArtifactRef[];
444
+ readonly outputArtifactRefs?: readonly ArtifactRef[];
445
+ readonly planId?: string;
446
+ }
447
+ interface SessionStore {
448
+ readonly kind: "session-store";
449
+ readonly id: string;
450
+ create(options?: CreateSessionOptions): Promise<SessionRecord>;
451
+ load(id: string): Promise<SessionRecord | undefined>;
452
+ save(session: SessionRecord): Promise<SessionRecord>;
453
+ branch(parentId: string, options?: Omit<CreateSessionOptions, "parentId">): Promise<SessionRecord>;
454
+ appendTurn(input: AppendSessionTurnInput): Promise<SessionRecord>;
455
+ }
456
+ interface MemorySessionStoreOptions {
457
+ readonly id?: string;
458
+ }
459
+ declare function createMemorySessionStore(options?: MemorySessionStoreOptions): SessionStore;
460
+ //#endregion
461
+ //#region src/context/context-pack.d.ts
462
+ interface ContextPack extends ContextPackPlan {
463
+ readonly kind: "context-pack";
464
+ }
465
+ interface ContextSummarizer {
466
+ summarize(input: {
467
+ readonly artifacts: readonly ArtifactRef[];
468
+ readonly budgetTokens: number;
469
+ }): Promise<readonly ArtifactRef[]> | readonly ArtifactRef[];
470
+ }
471
+ //#endregion
472
+ //#region src/providers/provider.d.ts
473
+ type CapabilityModality = "text" | "json" | "image" | "audio" | "video" | "document" | "file" | "url" | "tool";
474
+ type ProviderTransportMode = "inline" | "json" | "url" | "base64" | "provider-upload" | "file-id" | "extracted-text" | "transcript";
475
+ type ProviderLatencyClass = "interactive" | "batch";
476
+ interface ProviderPricingHint {
477
+ /** @deprecated prefer `inputPer1kTokens` — kept for backward compatibility */
478
+ readonly inputCostPer1M?: number;
479
+ /** @deprecated prefer `outputPer1kTokens` — kept for backward compatibility */
480
+ readonly outputCostPer1M?: number;
481
+ /** Per-1000-prompt-token cost in USD. Preferred field for Phase 7+ pricing. */
482
+ readonly inputPer1kTokens?: number;
483
+ /** Per-1000-completion-token cost in USD. Preferred field for Phase 7+ pricing. */
484
+ readonly outputPer1kTokens?: number;
485
+ }
486
+ /**
487
+ * Normalized per-run usage at the result layer.
488
+ *
489
+ * `costUsd` is `number | null` (not optional, not `0`) so downstream
490
+ * consumers can distinguish "free" (`0`) from "unmeasured" (`null`) when
491
+ * provider pricing is unknown — see 07-CONTEXT.md "Cost Normalization & Usage".
492
+ *
493
+ * Distinct from `UsageRecord` on `ProviderAttemptRecord`: `UsageRecord`
494
+ * is the per-attempt record, `Usage` is the per-run normalized shape
495
+ * surfaced on `RunSuccess` / `RunFailure`.
496
+ */
497
+ interface Usage {
498
+ readonly promptTokens: number;
499
+ readonly completionTokens: number;
500
+ readonly costUsd: number | null;
501
+ }
502
+ interface ProviderDataPolicyHints {
503
+ readonly privacy: readonly ("standard" | "sensitive" | "restricted")[];
504
+ readonly uploadRetention?: "none" | "ephemeral" | "provider-default";
505
+ readonly supportsNoLogging?: boolean;
506
+ readonly supportsNoTraining?: boolean;
507
+ }
508
+ interface ModelCapability {
509
+ readonly providerId: string;
510
+ readonly modelId: string;
511
+ readonly inputModalities: readonly CapabilityModality[];
512
+ readonly outputModalities: readonly CapabilityModality[];
513
+ readonly fileTransport: readonly ProviderTransportMode[];
514
+ readonly contextWindow: number;
515
+ readonly structuredOutput: boolean;
516
+ readonly toolUse: boolean;
517
+ readonly streaming: boolean;
518
+ readonly pricing?: ProviderPricingHint;
519
+ readonly latency: ProviderLatencyClass;
520
+ readonly dataPolicy: ProviderDataPolicyHints;
521
+ readonly available?: boolean;
522
+ }
523
+ interface ProviderRef {
524
+ readonly id: string;
525
+ readonly kind?: "provider-ref";
526
+ }
527
+ interface ProviderRunRequest {
528
+ readonly task: string;
529
+ readonly artifacts: readonly ArtifactInput[];
530
+ readonly outputs: readonly string[];
531
+ readonly outputContracts?: OutputContractMap;
532
+ readonly policy?: unknown;
533
+ readonly signal?: AbortSignal;
534
+ readonly plan?: ExecutionPlan;
535
+ readonly contextPack?: ContextPack;
536
+ readonly providerPackaging?: ProviderPackagingPlan;
537
+ readonly packagedArtifacts?: readonly ArtifactRef[];
538
+ }
539
+ interface ProviderRunResponse {
540
+ readonly rawOutputs: Record<string, unknown>;
541
+ readonly artifactRefs?: readonly (ArtifactInput | ArtifactRef)[];
542
+ /**
543
+ * @deprecated Legacy per-attempt usage shape. Phase 7+ adapters should
544
+ * populate `normalizedUsage` instead — Plan 04 will prefer `normalizedUsage`
545
+ * when wiring `RunResult.usage`. Kept here for backward compatibility with
546
+ * v1.0 adapters that already report this field.
547
+ */
548
+ readonly usage?: UsageRecord;
549
+ /**
550
+ * Phase 7 normalized usage shape for `RunResult.usage`. Populated by all
551
+ * Phase 7+ adapters (openai, openai-compat, ai-sdk, fake). `costUsd` is
552
+ * `null` when pricing is unknown (per the cost-normalization decision in
553
+ * 07-CONTEXT.md — distinguishes "free" from "unmeasured").
554
+ */
555
+ readonly normalizedUsage?: Usage;
556
+ readonly rawResponse?: unknown;
557
+ }
558
+ interface ProviderAdapter {
559
+ readonly id: string;
560
+ readonly kind: "provider-adapter";
561
+ readonly capabilities?: readonly ModelCapability[];
562
+ readonly execute?: (request: ProviderRunRequest) => Promise<ProviderRunResponse>;
563
+ }
564
+ type ProviderRegistryInput = readonly (ProviderRef | ProviderAdapter | string)[];
565
+ //#endregion
566
+ //#region src/plan/plan.d.ts
567
+ type ExecutionPlanStatus = "stub" | "planned" | "no-route" | "running" | "completed" | "failed";
568
+ type ExecutionStageKind = "analysis" | "transforms" | "context-packing" | "provider-packaging" | "tool-execution" | "execution" | "validation" | "tripwire" | "persistence" | "replay";
569
+ type ExecutionStageStatus = "pending" | "running" | "completed" | "skipped" | "failed";
570
+ interface ExecutionPlanStage {
571
+ readonly id: string;
572
+ readonly kind: ExecutionStageKind;
573
+ readonly status: ExecutionStageStatus;
574
+ readonly inputArtifacts?: readonly string[];
575
+ readonly outputArtifacts?: readonly string[];
576
+ readonly warnings: readonly string[];
577
+ readonly metadata?: Record<string, unknown>;
578
+ }
579
+ interface RouteRejectReason {
580
+ readonly code: string;
581
+ readonly message: string;
582
+ }
583
+ interface RouteCandidate {
584
+ readonly providerId: string;
585
+ readonly modelId: string;
586
+ readonly capability: ModelCapability;
587
+ readonly score: number;
588
+ readonly accepted: boolean;
589
+ readonly reasons: readonly RouteRejectReason[];
590
+ readonly estimates: RouteEstimates;
591
+ }
592
+ interface RouteEstimates {
593
+ readonly inputTokens: number;
594
+ readonly outputTokens: number;
595
+ readonly costUsd?: number;
596
+ readonly latencyMs?: number;
597
+ }
598
+ interface SelectedRoute {
599
+ readonly providerId: string;
600
+ readonly modelId: string;
601
+ readonly score: number;
602
+ readonly estimates: RouteEstimates;
603
+ readonly inputModalities: readonly CapabilityModality[];
604
+ readonly outputModalities: readonly CapabilityModality[];
605
+ readonly fileTransport: readonly ProviderTransportMode[];
606
+ }
607
+ interface FallbackRoute {
608
+ readonly providerId: string;
609
+ readonly modelId: string;
610
+ readonly score: number;
611
+ readonly reason: "policy-preserving-fallback";
612
+ }
613
+ interface RouteDecision {
614
+ readonly catalogVersion: string;
615
+ readonly selected?: SelectedRoute;
616
+ readonly candidates: readonly RouteCandidate[];
617
+ readonly rejected: readonly RouteCandidate[];
618
+ readonly fallbackChain: readonly FallbackRoute[];
619
+ readonly noRouteReasons: readonly RouteRejectReason[];
620
+ }
621
+ interface ContextPackPlan {
622
+ readonly id: string;
623
+ readonly tokenBudget: number;
624
+ readonly estimatedTokens: number;
625
+ readonly included: readonly ContextPackItemPlan[];
626
+ readonly summarized: readonly ContextPackItemPlan[];
627
+ readonly archived: readonly ContextPackItemPlan[];
628
+ readonly omitted: readonly ContextPackItemPlan[];
629
+ readonly warnings: readonly string[];
630
+ }
631
+ interface ContextPackItemPlan {
632
+ readonly artifactId?: string;
633
+ readonly sessionTurnId?: string;
634
+ readonly reason: string;
635
+ readonly estimatedTokens: number;
636
+ readonly trust: "developer" | "user" | "tool" | "model-summary";
637
+ }
638
+ interface ProviderPackagingPlan {
639
+ readonly providerId: string;
640
+ readonly modelId: string;
641
+ readonly artifacts: readonly ProviderPackagedArtifactPlan[];
642
+ readonly warnings: readonly string[];
643
+ }
644
+ interface ProviderPackagedArtifactPlan {
645
+ readonly artifactId: string;
646
+ readonly transport: ProviderTransportMode;
647
+ readonly mediaType?: string;
648
+ readonly lineageTransform: "provider-packaging";
649
+ readonly warnings: readonly string[];
650
+ }
651
+ interface ProviderAttemptRecord {
652
+ readonly providerId: string;
653
+ readonly modelId: string;
654
+ readonly status: "pending" | "running" | "succeeded" | "failed" | "cancelled";
655
+ readonly startedAt?: string;
656
+ readonly completedAt?: string;
657
+ readonly error?: string;
658
+ readonly usage?: UsageRecord;
659
+ }
660
+ interface UsageRecord {
661
+ readonly inputTokens?: number;
662
+ readonly outputTokens?: number;
663
+ readonly totalTokens?: number;
664
+ readonly costUsd?: number;
665
+ readonly latencyMs?: number;
666
+ }
667
+ interface ExecutionPlan {
668
+ readonly id: string;
669
+ readonly kind: "execution-plan";
670
+ readonly version: 1;
671
+ readonly createdAt: string;
672
+ readonly status: ExecutionPlanStatus;
673
+ readonly task: string;
674
+ readonly outputNames: readonly string[];
675
+ readonly artifactRefs: readonly ArtifactRef[];
676
+ readonly route: RouteDecision;
677
+ readonly stages: readonly ExecutionPlanStage[];
678
+ readonly context?: ContextPackPlan;
679
+ readonly providerPackaging?: ProviderPackagingPlan;
680
+ readonly attempts: readonly ProviderAttemptRecord[];
681
+ readonly warnings: readonly string[];
682
+ readonly metadata?: Record<string, unknown>;
683
+ }
684
+ interface ExecutionPlanStub {
685
+ readonly id: string;
686
+ readonly kind: "plan-stub";
687
+ readonly createdAt: string;
688
+ readonly status: "stub";
689
+ readonly stages: readonly [];
690
+ readonly warnings: readonly string[];
691
+ }
692
+ type ResultPlan = ExecutionPlan | ExecutionPlanStub;
693
+ //#endregion
694
+ //#region src/receipts/types.d.ts
695
+ type ContractVerdict = "success" | "tripwire-violated" | "no-contract-match" | "execution-failed" | "validation-failed";
696
+ interface ReceiptUsageCanonical {
697
+ readonly promptTokens: number;
698
+ readonly completionTokens: number;
699
+ readonly costUsd: string | null;
700
+ }
701
+ interface ReceiptModel {
702
+ readonly requested: string;
703
+ readonly observed: string | null;
704
+ }
705
+ interface ReceiptRoute {
706
+ readonly providerId: string;
707
+ readonly capabilityId: string;
708
+ readonly attemptNumber: number;
709
+ }
710
+ interface ReceiptRedaction {
711
+ readonly path: string;
712
+ readonly reason: string;
713
+ }
714
+ interface CapabilityReceiptBody {
715
+ readonly version: "lattice-receipt/v1" | "lattice-receipt/v1.1";
716
+ readonly receiptId: string;
717
+ readonly runId: string;
718
+ readonly issuedAt: string;
719
+ readonly kid: string;
720
+ readonly model: ReceiptModel;
721
+ readonly route: ReceiptRoute;
722
+ readonly usage: ReceiptUsageCanonical;
723
+ readonly contractVerdict: ContractVerdict;
724
+ readonly contractHash: string | null;
725
+ readonly inputHashes: readonly string[];
726
+ readonly outputHash: string | null;
727
+ readonly redactionPolicyId: string;
728
+ readonly redactions: readonly ReceiptRedaction[];
729
+ readonly noRouteReasons?: readonly RouteRejectReason[];
730
+ readonly tripwireEvidence?: TripwireEvidence;
731
+ readonly stepName?: string;
732
+ readonly stepIndex?: number;
733
+ readonly parentStepName?: string;
734
+ readonly previousStepName?: string;
735
+ readonly sessionId?: string;
736
+ readonly timestamp?: string;
737
+ }
738
+ interface ReceiptSignature {
739
+ readonly keyid: string;
740
+ readonly sig: string;
741
+ }
742
+ interface ReceiptEnvelope {
743
+ readonly payloadType: "application/vnd.lattice.receipt+json";
744
+ readonly payload: string;
745
+ readonly signatures: readonly ReceiptSignature[];
746
+ }
747
+ interface ReceiptSigner {
748
+ readonly kid: string;
749
+ sign(bytes: Uint8Array): Promise<Uint8Array>;
750
+ readonly publicKeyJwk: JsonWebKey;
751
+ }
752
+ type KeyState = "active" | "retired" | "revoked";
753
+ interface KeyEntry {
754
+ readonly kid: string;
755
+ readonly publicKeyJwk: JsonWebKey;
756
+ readonly state: KeyState;
757
+ }
758
+ interface KeySet {
759
+ lookup(kid: string): KeyEntry | undefined;
760
+ }
761
+ type VerifyErrorKind = "key-not-found" | "key-revoked" | "canonicalization-mismatch" | "signature-invalid" | "envelope-malformed" | "version-mismatch" | "schema-version-too-low";
762
+ interface VerifyError {
763
+ readonly kind: VerifyErrorKind;
764
+ readonly message: string;
765
+ }
766
+ interface VerifyOk {
767
+ readonly ok: true;
768
+ readonly body: CapabilityReceiptBody;
769
+ readonly keyState: KeyState;
770
+ }
771
+ interface VerifyFail {
772
+ readonly ok: false;
773
+ readonly error: VerifyError;
774
+ }
775
+ type VerifyResult = VerifyOk | VerifyFail;
776
+ //#endregion
777
+ //#region src/receipts/receipt.d.ts
778
+ /**
779
+ * Public input to createReceipt. Mirrors CapabilityReceiptBody minus:
780
+ * - `version` (forced to "lattice-receipt/v1.1" per CRYPTO-01)
781
+ * - `kid` (forced from signer.kid — caller cannot mismatch)
782
+ * - `redactions[]` (populated by redactReceiptBody)
783
+ * - `usage.costUsd` (converted to canonical string by usageToCanonical)
784
+ *
785
+ * receiptId and issuedAt default to runtime-generated values when omitted.
786
+ * redactionPolicyId defaults to DEFAULT_REDACTION_POLICY_ID.
787
+ */
788
+ interface CreateReceiptInput {
789
+ readonly runId: string;
790
+ readonly issuedAt?: string;
791
+ readonly receiptId?: string;
792
+ readonly model: ReceiptModel;
793
+ readonly route: ReceiptRoute;
794
+ readonly usage: Usage;
795
+ readonly contractVerdict: ContractVerdict;
796
+ readonly contractHash: string | null;
797
+ readonly inputHashes: readonly string[];
798
+ readonly outputHash: string | null;
799
+ readonly redactionPolicyId?: string;
800
+ readonly noRouteReasons?: readonly RouteRejectReason[];
801
+ readonly tripwireEvidence?: TripwireEvidence;
802
+ readonly stepName?: string;
803
+ readonly stepIndex?: number;
804
+ readonly parentStepName?: string;
805
+ readonly previousStepName?: string;
806
+ readonly sessionId?: string;
807
+ readonly timestamp?: string;
808
+ }
809
+ /**
810
+ * Build, redact, canonicalize, sign, and envelope a CapabilityReceipt.
811
+ *
812
+ * Ordering INVARIANT (09-CONTEXT.md, PITFALLS.md Pitfall #1):
813
+ * redact -> canonicalize -> PAE -> sign -> encode
814
+ *
815
+ * The signed digest commits to canonicalize(redact(body)). The function
816
+ * structure makes any other ordering impossible to write by accident —
817
+ * canonicalizeReceiptBody is ONLY called on the output of redactReceiptBody.
818
+ *
819
+ * Defense in depth:
820
+ * - body.kid is assigned from signer.kid, never from input (input has no
821
+ * kid field). The signed body and the envelope keyid CANNOT disagree by
822
+ * construction.
823
+ * - signer.kid is also written to envelope.signatures[0].keyid, so the
824
+ * verifier can cross-check (Step 7 of verifyReceipt).
825
+ *
826
+ * I-JSON guarantees: usage.costUsd is converted to string (or null) via
827
+ * usageToCanonical. Receipts NEVER carry raw floats in the canonical form.
828
+ */
829
+ declare function createReceipt(input: CreateReceiptInput, signer: ReceiptSigner): Promise<ReceiptEnvelope>;
830
+ //#endregion
831
+ //#region src/contract/checkpoint.d.ts
832
+ /**
833
+ * The tracer event name Lattice's checkpoint hook emits per step transition.
834
+ * Identical to the literal added to RunEventKind in tracing.ts.
835
+ */
836
+ declare const STEP_TRANSITION_EVENT_NAME: "step.transition";
837
+ /**
838
+ * Default band convention for the checkpoint hook (D-06). The caller is
839
+ * free to register in a different band but the documented convention is
840
+ * OBSERVABILITY -- between SAFETY (runs first) and EXTENSION (runs last).
841
+ */
842
+ declare const DEFAULT_CHECKPOINT_BAND: Band;
843
+ /**
844
+ * Per-step context the caller passes through the hook pipeline.
845
+ *
846
+ * Fields are stable identifiers (D-04 carryforward); do NOT populate with
847
+ * user content -- they appear cleartext in the signed receipt body.
848
+ *
849
+ * - stepName: required. Stable identifier for this step.
850
+ * - stepIndex: required. Monotonically increasing ordinal; caller-owned.
851
+ * - parentStepName: optional. Names the enclosing step when nested.
852
+ * - previousStepName: optional. Names the immediately-prior step in the
853
+ * linked-list timeline (D-09 linked-list threading).
854
+ * - timestamp: required. ISO-8601 RFC 3339.
855
+ */
856
+ interface CheckpointHookContext {
857
+ readonly stepName: string;
858
+ readonly stepIndex: number;
859
+ readonly parentStepName?: string;
860
+ readonly previousStepName?: string;
861
+ readonly timestamp: string;
862
+ }
863
+ /**
864
+ * The factory's options.
865
+ *
866
+ * - runId: required. Threaded into every receipt body + every tracer event.
867
+ * - tracer: optional. When omitted, the handler still mints (when signer
868
+ * present) but does NOT emit a tracer event. When provided, the handler
869
+ * ALWAYS emits exactly one event per invocation (independent of mint
870
+ * success/failure per D-10).
871
+ * - signer: optional. When omitted, the handler emits a tracer event only
872
+ * (no mint attempted). When provided, the handler attempts to mint via
873
+ * createReceipt(...) inside a try/catch (D-07 best-effort).
874
+ * - sessionId: optional. Threaded into receipt body and event metadata.
875
+ * - model: optional. ReceiptModel descriptor for the receipt body; the
876
+ * factory provides a sensible "step" default when omitted.
877
+ * - route: optional. ReceiptRoute descriptor for the receipt body; the
878
+ * factory provides a sensible "step" default when omitted.
879
+ * - contractVerdict: optional. Defaults to "success" -- step transitions
880
+ * are observability events, not contract evaluations.
881
+ */
882
+ interface CheckpointHookOptions {
883
+ readonly runId: string;
884
+ readonly tracer?: TracerLike;
885
+ readonly signer?: ReceiptSigner;
886
+ readonly sessionId?: string;
887
+ readonly model?: ReceiptModel;
888
+ readonly route?: ReceiptRoute;
889
+ readonly contractVerdict?: CreateReceiptInput["contractVerdict"];
890
+ }
891
+ /**
892
+ * Build a checkpoint hook handler.
893
+ *
894
+ * The returned handler is suitable for registration on a HookPipeline
895
+ * created via createHookPipeline (see ./bands.ts). The handler does not
896
+ * auto-register; the caller passes it to pipeline.register(...) with the
897
+ * desired lifecycle event (typically AFTER_TOOL or BEFORE_TOOL) and band
898
+ * (typically BAND.OBSERVABILITY, exported as DEFAULT_CHECKPOINT_BAND).
899
+ *
900
+ * Per-invocation behavior:
901
+ * 1. Build event metadata from options + per-call context.
902
+ * 2. If signer is configured, attempt createReceipt(...) inside a
903
+ * try/catch. On success, set metadata.receiptId + metadata.envelope.
904
+ * On failure, set metadata.mintError (string from caught error).
905
+ * 3. If tracer is configured, emit exactly one tracer.event?.(
906
+ * STEP_TRANSITION_EVENT_NAME, metadata) call.
907
+ * 4. Return void.
908
+ *
909
+ * NO upstream throw (D-07). NO global mutation (D-05).
910
+ */
911
+ declare function createCheckpointHook(options: CheckpointHookOptions): HookHandler<CheckpointHookContext>;
912
+ //#endregion
913
+ //#region src/contract/contract.d.ts
914
+ /**
915
+ * Budget invariant declaration attached to a CapabilityContract.
916
+ *
917
+ * Phase 7 implements `maxCostUsd` enforcement at pre-flight. The
918
+ * `p95LatencyMs` field is declared per CONTRACT-02 but is informational
919
+ * only in Phase 7 — latency observations are wired in a later phase.
920
+ *
921
+ * Phase 19 (v1.2) adds `maxIterations` and `maxWallTimeMs` for the agent
922
+ * runtime. Both are additive and optional; non-agent callers ignore them.
923
+ * `maxIterations` caps the number of `runAgent` iterations; `maxWallTimeMs`
924
+ * caps wall-clock duration per `runAgent` invocation. Both are enforced
925
+ * pre-iteration in the agent loop.
926
+ */
927
+ interface BudgetInvariant {
928
+ readonly maxCostUsd?: number;
929
+ readonly maxIterations?: number;
930
+ readonly maxWallTimeMs?: number;
931
+ readonly p95LatencyMs?: number;
932
+ }
933
+ /**
934
+ * Quality-floor invariant.
935
+ *
936
+ * `suite` is a fixture-directory path string; `minScore` is in 0..1.
937
+ * Phase 7 forwards this into the pre-flight evaluator but only enforces
938
+ * capability-side rejects. Full enforcement lives in Phase 12 (`lattice eval`).
939
+ */
940
+ interface QualityFloorInvariant {
941
+ readonly suite: string;
942
+ readonly minScore: number;
943
+ }
944
+ /**
945
+ * The full Capability Contract attached to `RunIntent.contract`.
946
+ *
947
+ * All fields are optional. v1.0 callers compile and run unchanged when
948
+ * the field is omitted entirely. PROJECT.md explicitly rejects mandatory
949
+ * contracts.
950
+ */
951
+ interface CapabilityContract {
952
+ readonly kind: "capability-contract";
953
+ readonly budget?: BudgetInvariant;
954
+ readonly invariants?: readonly InvariantDeclaration[];
955
+ readonly qualityFloor?: QualityFloorInvariant;
956
+ readonly requiredModalities?: readonly CapabilityModality[];
957
+ readonly requiredPrivacy?: "standard" | "sensitive" | "restricted";
958
+ }
959
+ /**
960
+ * Reject-reason taxonomy added to `RouteRejectReason.code` by Phase 7's
961
+ * pre-flight evaluator. Closed four-value union per the locked decisions
962
+ * in 07-CONTEXT.md.
963
+ */
964
+ type ContractRejectReasonCode = "contract-budget-exceeded" | "contract-quality-floor" | "contract-modality-missing" | "contract-privacy-mismatch";
965
+ /** Input shape accepted by `contract()`. Mirrors `CapabilityContract` minus `kind`. */
966
+ interface CapabilityContractInput {
967
+ readonly budget?: BudgetInvariant;
968
+ readonly invariants?: readonly InvariantDeclaration[];
969
+ readonly qualityFloor?: QualityFloorInvariant;
970
+ readonly requiredModalities?: readonly CapabilityModality[];
971
+ readonly requiredPrivacy?: "standard" | "sensitive" | "restricted";
972
+ }
973
+ /**
974
+ * Factory for `CapabilityContract` values.
975
+ *
976
+ * Mirrors the `output()` and adapter factory style — exact-optional safe
977
+ * (does not emit `field: undefined` properties under `exactOptionalPropertyTypes`).
978
+ * Returns a frozen value with frozen nested objects so downstream code can
979
+ * rely on structural immutability when canonicalizing in Phase 9.
980
+ */
981
+ declare function contract(input?: CapabilityContractInput): CapabilityContract;
982
+ //#endregion
983
+ //#region src/contract/preflight.d.ts
984
+ /**
985
+ * Result of a single pre-flight contract evaluation against a candidate
986
+ * capability. `reasons` is empty when `ok` is true and contains one or more
987
+ * `RouteRejectReason` entries when `ok` is false.
988
+ *
989
+ * The evaluator surfaces ALL failing reasons in a single pass — not the
990
+ * first-failing only — so the deterministic router can aggregate per-candidate
991
+ * rejection detail (CONTEXT.md "Pre-flight surfaces ALL failed candidates
992
+ * with per-candidate rejection reasons").
993
+ */
994
+ interface ContractPreflightResult {
995
+ readonly ok: boolean;
996
+ readonly reasons: readonly RouteRejectReason[];
997
+ }
998
+ /**
999
+ * Input for the pure cost estimator. Token counts come from the router's
1000
+ * existing `estimateRoute()` helper so preflight and router agree on the
1001
+ * projected output size (one source of truth — see `evaluateContractAgainstRoute`).
1002
+ */
1003
+ interface EstimateRouteCostInput {
1004
+ readonly capability: ModelCapability;
1005
+ readonly estimatedInputTokens: number;
1006
+ readonly estimatedOutputTokens: number;
1007
+ }
1008
+ /**
1009
+ * Pure cost estimator. Returns `null` when pricing is unknown (so downstream
1010
+ * gates can distinguish "free / zero" from "unmeasured" per the Phase 7
1011
+ * cost-normalization decision). Uses static catalog metadata only — no probes,
1012
+ * no external pricing APIs.
1013
+ */
1014
+ declare function estimateRouteCost(input: EstimateRouteCostInput): number | null;
1015
+ /** Input for the pre-flight evaluator. */
1016
+ interface EvaluateContractInput {
1017
+ readonly capability: ModelCapability;
1018
+ readonly estimatedInputTokens: number;
1019
+ readonly estimatedOutputTokens: number;
1020
+ }
1021
+ /**
1022
+ * Pure pre-flight evaluator. Phase 9 receipts will reuse this for deterministic
1023
+ * verdict reconstruction.
1024
+ *
1025
+ * Token estimation: Phase 7 does NOT define a separate token estimator. Output-
1026
+ * token projection is the canonical responsibility of the router's existing
1027
+ * `estimateRoute()` helper (in `routing/router.ts`), which already produces an
1028
+ * `estimatedOutputTokens` value. The router passes that same value into this
1029
+ * evaluator via `EvaluateContractInput.estimatedOutputTokens`, so preflight
1030
+ * and the router always agree on the projected output size. Phase 9 receipts
1031
+ * will pin the router's estimate as the deterministic input — intentionally
1032
+ * one source of truth.
1033
+ *
1034
+ * Reject taxonomy (Phase 7 emits three of four codes):
1035
+ * - `contract-budget-exceeded` (CONTRACT-04 + COST-03)
1036
+ * - `contract-modality-missing` (CONTRACT-06)
1037
+ * - `contract-privacy-mismatch` (CONTRACT-06)
1038
+ * - `contract-quality-floor` (reserved for Phase 12 `lattice eval`; NEVER emitted here)
1039
+ */
1040
+ declare function evaluateContractAgainstRoute(contract: CapabilityContract | undefined, input: EvaluateContractInput): ContractPreflightResult;
1041
+ //#endregion
1042
+ //#region src/receipts/keyset.d.ts
1043
+ /**
1044
+ * In-memory KeySet factory.
1045
+ *
1046
+ * Verification flow (plan 09-03):
1047
+ * - keySet.lookup(kid) returns undefined → VerifyError {kind: "key-not-found"}
1048
+ * - entry.state === "revoked" → VerifyError {kind: "key-revoked"}
1049
+ * - entry.state === "retired" → VerifyOk + keyState: "retired" (caller may warn)
1050
+ * - entry.state === "active" → VerifyOk + keyState: "active"
1051
+ *
1052
+ * Duplicate kids: last write wins (deterministic — callers control entry order).
1053
+ * Empty entries array is legal — every lookup returns undefined.
1054
+ * Returned KeySet exposes only `lookup` — no enumeration.
1055
+ *
1056
+ * See 09-CONTEXT.md "Key Management (UNRETROFITTABLE)".
1057
+ */
1058
+ declare function createMemoryKeySet(entries: readonly KeyEntry[]): KeySet;
1059
+ //#endregion
1060
+ //#region src/receipts/sign.d.ts
1061
+ interface GeneratedEd25519KeyPair {
1062
+ readonly privateKeyJwk: JsonWebKey;
1063
+ readonly publicKeyJwk: JsonWebKey;
1064
+ }
1065
+ declare function generateEd25519KeyPairJwk(): Promise<GeneratedEd25519KeyPair>;
1066
+ declare function createInMemorySigner(privateKeyJwk: JsonWebKey, options: {
1067
+ readonly kid: string;
1068
+ readonly publicKeyJwk: JsonWebKey;
1069
+ }): ReceiptSigner;
1070
+ //#endregion
1071
+ //#region src/receipts/verify.d.ts
1072
+ /**
1073
+ * Pure receipt verifier.
1074
+ *
1075
+ * Returns a typed VerifyResult — never throws across the verification
1076
+ * boundary (PITFALLS.md security: "Verifier panics on malformed receipts
1077
+ * -> DoS via crafted input"). All parsing failures become typed errors.
1078
+ *
1079
+ * Decision tree (first match wins):
1080
+ * 1. decodeEnvelope throws OR signatures[] empty -> envelope-malformed
1081
+ * 2. payload bytes are not valid JSON -> envelope-malformed
1082
+ * 3. body shape check fails OR version unknown literal -> version-mismatch
1083
+ * 4. body.version === undefined OR "lattice-receipt/v1"-> schema-version-too-low (CRYPTO-01)
1084
+ * 5. keySet.lookup(keyid) === undefined -> key-not-found
1085
+ * 6. entry.state === "revoked" -> key-revoked
1086
+ * 7. re-canonicalized body != signed payloadBytes -> canonicalization-mismatch
1087
+ * 8. Ed25519 verification of PAE fails -> signature-invalid
1088
+ * 9. body.kid !== entry.kid (defense in depth) -> signature-invalid
1089
+ * 10. otherwise -> ok + keyState
1090
+ */
1091
+ declare function verifyReceipt(envelope: ReceiptEnvelope, keySet: KeySet): Promise<VerifyResult>;
1092
+ //#endregion
1093
+ //#region src/results/errors.d.ts
1094
+ interface ValidationIssue {
1095
+ readonly message: string;
1096
+ readonly path?: readonly (string | number | symbol)[];
1097
+ }
1098
+ interface ValidationError {
1099
+ readonly kind: "validation";
1100
+ readonly message: string;
1101
+ readonly output?: string;
1102
+ readonly issues: readonly ValidationIssue[];
1103
+ }
1104
+ interface ExecutionUnavailableError {
1105
+ readonly kind: "execution_unavailable";
1106
+ readonly message: string;
1107
+ }
1108
+ interface NoRouteError {
1109
+ readonly kind: "no_route";
1110
+ readonly message: string;
1111
+ readonly reasons: readonly string[];
1112
+ }
1113
+ interface ProviderExecutionError {
1114
+ readonly kind: "provider_execution";
1115
+ readonly message: string;
1116
+ readonly providerId?: string;
1117
+ readonly modelId?: string;
1118
+ }
1119
+ interface TimeoutError {
1120
+ readonly kind: "timeout";
1121
+ readonly message: string;
1122
+ }
1123
+ /**
1124
+ * Phase 7 addition: emitted by the runtime when no candidate route can
1125
+ * satisfy the caller-supplied `CapabilityContract` (budget, modality,
1126
+ * privacy, or quality-floor invariants).
1127
+ *
1128
+ * `noRouteReasons` carries the full deterministic-router rejection list
1129
+ * so callers can inspect per-candidate detail. Phase 9 (receipts) will
1130
+ * persist this array for deterministic verdict reconstruction.
1131
+ */
1132
+ interface NoContractMatchError {
1133
+ readonly kind: "no-contract-match";
1134
+ readonly message: string;
1135
+ readonly noRouteReasons: readonly RouteRejectReason[];
1136
+ }
1137
+ /**
1138
+ * Phase 8 addition: emitted when a `CapabilityContract.invariants` tripwire
1139
+ * fires after the provider returned a schema-valid output. Carries the
1140
+ * `TripwireEvidence` produced by `evaluateTripwires`.
1141
+ *
1142
+ * `terminal: true` is a structural marker — combined with the `isTerminal()`
1143
+ * predicate it tells the fallback chain in `runWithConfig` to refuse retry.
1144
+ * `NoContractMatchError` does NOT carry the field (to avoid breaking Phase 7
1145
+ * callers) but `isTerminal()` still returns true for it via the kind check.
1146
+ */
1147
+ interface TripwireViolationError {
1148
+ readonly kind: "tripwire-violated";
1149
+ readonly message: string;
1150
+ readonly invariantId: string;
1151
+ readonly evidence: TripwireEvidence;
1152
+ readonly terminal: true;
1153
+ }
1154
+ type LatticeRunError = ValidationError | ExecutionUnavailableError | NoRouteError | ProviderExecutionError | TimeoutError | NoContractMatchError | TripwireViolationError;
1155
+ /**
1156
+ * Returns `true` for run errors that MUST NOT be retried by the fallback
1157
+ * chain. Phase 8 covers two kinds:
1158
+ *
1159
+ * - `tripwire-violated` — the contract's invariants rejected the output;
1160
+ * a different provider will not change the verdict, so retry burns
1161
+ * budget for no gain (T-08-06 in 08-02-PLAN threat register).
1162
+ * - `no-contract-match` — no route satisfies the contract at all; the
1163
+ * run never executed and no retry will help.
1164
+ *
1165
+ * All other error kinds return `false` and remain eligible for fallback.
1166
+ * The predicate is exported so Phase 12's eval gate and any user-side
1167
+ * retry wrappers can share one source of truth.
1168
+ */
1169
+ declare function isTerminal(error: LatticeRunError): boolean;
1170
+ //#endregion
1171
+ //#region src/providers/adapters.d.ts
1172
+ interface OpenAICompatibleProviderOptions {
1173
+ readonly id?: string;
1174
+ readonly model: string;
1175
+ readonly baseUrl: string;
1176
+ readonly apiKey?: string;
1177
+ readonly fetch?: typeof fetch;
1178
+ /**
1179
+ * Phase 7 addition: caller-supplied per-1k pricing. When provided, the
1180
+ * adapter computes `normalizedUsage.costUsd` from the API-reported token
1181
+ * counts. When omitted, `normalizedUsage.costUsd` is `null` so downstream
1182
+ * consumers can distinguish "unmeasured" from "free" (per 07-CONTEXT.md).
1183
+ */
1184
+ readonly pricing?: {
1185
+ readonly inputPer1kTokens?: number;
1186
+ readonly outputPer1kTokens?: number;
1187
+ };
1188
+ }
1189
+ interface SdkLikeProviderOptions {
1190
+ readonly id?: string;
1191
+ readonly model: string;
1192
+ readonly generate: (input: {
1193
+ readonly task: string;
1194
+ readonly outputNames: readonly string[];
1195
+ }) => Promise<ProviderRunResponse> | ProviderRunResponse;
1196
+ }
1197
+ declare function createOpenAICompatibleProvider(options: OpenAICompatibleProviderOptions): ProviderAdapter;
1198
+ declare function createOpenAIProvider(options: OpenAICompatibleProviderOptions): ProviderAdapter;
1199
+ declare function createAISdkProvider(options: SdkLikeProviderOptions): ProviderAdapter;
1200
+ //#endregion
1201
+ //#region src/providers/anthropic.d.ts
1202
+ /**
1203
+ * Options for {@link createAnthropicProvider}.
1204
+ *
1205
+ * Mirrors `OpenAICompatibleProviderOptions` ergonomics (Phase 7 pattern) but
1206
+ * for the Anthropic Messages API at `/v1/messages` -- which uses a top-level
1207
+ * `system` field and a `content[0].text` response shape that diverges from
1208
+ * the OpenAI Chat Completions schema (see FSB v0.9.x `extension/ai/universal-provider.js`
1209
+ * lines 280-297 + 566-573 for the production reference).
1210
+ *
1211
+ * SECURITY: `apiKey` is a runtime parameter -- do NOT hardcode or log it.
1212
+ *
1213
+ * DEFERRED (Phase 4 carryforward notes):
1214
+ * - prompt caching (deferred to a follow-on phase)
1215
+ * - streaming (deferred; this adapter is single-shot Promise -- per CONTEXT.md D-06)
1216
+ * - tool use (Anthropic tool_use blocks are deferred)
1217
+ * - resume-from-eviction -- see Phase 5 (MV3-survivability adapter contract)
1218
+ *
1219
+ * Ref: FSB v0.10.0-attempt-2 Phase 4 (D-02 + D-07: full custom adapter; preserve top-level `system`).
1220
+ */
1221
+ interface AnthropicProviderOptions {
1222
+ readonly id?: string;
1223
+ readonly model: string;
1224
+ readonly apiKey: string;
1225
+ /** Defaults to `https://api.anthropic.com`. Override for proxies. */
1226
+ readonly baseUrl?: string;
1227
+ /** Defaults to `2023-06-01`. Override only if the consumer has tested a newer pinned version. */
1228
+ readonly anthropicVersion?: string;
1229
+ readonly fetch?: typeof fetch;
1230
+ readonly pricing?: {
1231
+ readonly inputPer1kTokens?: number;
1232
+ readonly outputPer1kTokens?: number;
1233
+ };
1234
+ }
1235
+ declare function createAnthropicProvider(options: AnthropicProviderOptions): ProviderAdapter;
1236
+ //#endregion
1237
+ //#region src/providers/fake.d.ts
1238
+ interface FakeProviderOptions {
1239
+ readonly id?: string;
1240
+ readonly modelId?: string;
1241
+ readonly response?: ProviderRunResponse | ((request: ProviderRunRequest) => ProviderRunResponse | Promise<ProviderRunResponse>);
1242
+ readonly artifacts?: readonly ArtifactInput[];
1243
+ /**
1244
+ * Phase 7 addition: when provided, REPLACES the default single-capability
1245
+ * array so callers (notably Plan 07-04's modality/privacy reject tests)
1246
+ * can construct a fake adapter with arbitrary
1247
+ * `inputModalities` / `outputModalities` / `dataPolicy` / `pricing`
1248
+ * without mutating the returned adapter's readonly `capabilities` array.
1249
+ * When omitted, the existing default capability is used.
1250
+ */
1251
+ readonly capabilities?: readonly ModelCapability[];
1252
+ }
1253
+ declare function createFakeProvider(options?: FakeProviderOptions): ProviderAdapter;
1254
+ //#endregion
1255
+ //#region src/providers/gemini.d.ts
1256
+ /**
1257
+ * Options for {@link createGeminiProvider}.
1258
+ *
1259
+ * Mirrors `OpenAICompatibleProviderOptions` ergonomics (Phase 7 pattern) but
1260
+ * for Google's Generative Language API at
1261
+ * `/v1beta/models/{model}:generateContent` -- which uses `contents[].parts[].text`
1262
+ * (NOT OpenAI's `messages[]`), `role: "model"` for assistant turns (NOT
1263
+ * `"assistant"`), authenticates via `?key=` query string, and applies a
1264
+ * 4-category `safetySettings` block at `BLOCK_NONE` thresholds (FSB convention
1265
+ * mirrored from `extension/ai/universal-provider.js:255-272`).
1266
+ *
1267
+ * SECURITY: `apiKey` is a runtime parameter -- do NOT hardcode or log it.
1268
+ *
1269
+ * DEFERRED (Phase 4 carryforward notes):
1270
+ * - multimodal (vision) -- deferred
1271
+ * - streaming -- deferred (single-shot Promise per CONTEXT.md D-06)
1272
+ * - tool use -- deferred
1273
+ * - resume-from-eviction -- see Phase 5 (MV3-survivability adapter contract)
1274
+ *
1275
+ * Ref: FSB v0.10.0-attempt-2 Phase 4 (D-02 + D-07: full custom adapter; preserve role:"model").
1276
+ */
1277
+ interface GeminiProviderOptions {
1278
+ readonly id?: string;
1279
+ readonly model: string;
1280
+ readonly apiKey: string;
1281
+ /** Defaults to `https://generativelanguage.googleapis.com`. */
1282
+ readonly baseUrl?: string;
1283
+ readonly fetch?: typeof fetch;
1284
+ readonly pricing?: {
1285
+ readonly inputPer1kTokens?: number;
1286
+ readonly outputPer1kTokens?: number;
1287
+ };
1288
+ }
1289
+ declare function createGeminiProvider(options: GeminiProviderOptions): ProviderAdapter;
1290
+ //#endregion
1291
+ //#region src/providers/lm-studio.d.ts
1292
+ /**
1293
+ * Options for {@link createLmStudioProvider}.
1294
+ *
1295
+ * Thin wrapper around {@link createOpenAICompatibleProvider} pinned to
1296
+ * LM Studio's default local server URL `http://localhost:1234/v1`. Wire
1297
+ * shape is OpenAI Chat Completions. LM Studio is no-auth by convention
1298
+ * (CD-03): `apiKey` is OPTIONAL; when omitted, the underlying factory
1299
+ * sends no `Authorization` header (see
1300
+ * `lattice/packages/lattice/src/providers/adapters.ts:53` for the
1301
+ * conditional auth-header wiring).
1302
+ *
1303
+ * DEFERRED (D-16 carryforward):
1304
+ * - latency-tail diagnostics -- observability concern; LM Studio is
1305
+ * the canary for latency tails (INV-03);
1306
+ * diagnostics module deferred to a
1307
+ * follow-on observability phase.
1308
+ * - streaming -- deferred (single-shot per D-06).
1309
+ * - resume-from-eviction -- see Phase 5 (MV3-survivability adapter).
1310
+ *
1311
+ * Ref: FSB v0.10.0-attempt-2 Phase 4 (D-03: thin wrapper; D-16: latency-tail deferred; CD-03 no-opt-out).
1312
+ */
1313
+ interface LmStudioProviderOptions extends Omit<OpenAICompatibleProviderOptions, "id" | "baseUrl" | "apiKey"> {
1314
+ readonly id?: string;
1315
+ /** Defaults to `http://localhost:1234/v1`. Override for non-localhost deployments. */
1316
+ readonly baseUrl?: string;
1317
+ /**
1318
+ * Optional. LM Studio is no-auth by convention (CD-03 default).
1319
+ * When provided, sent as `Authorization: Bearer <apiKey>` (matches the
1320
+ * underlying OpenAI-compat factory). Use only for proxied LM Studio
1321
+ * deployments that have a token gate in front.
1322
+ */
1323
+ readonly apiKey?: string;
1324
+ }
1325
+ declare function createLmStudioProvider(options: LmStudioProviderOptions): ProviderAdapter;
1326
+ //#endregion
1327
+ //#region src/providers/openrouter.d.ts
1328
+ /**
1329
+ * Options for {@link createOpenRouterProvider}.
1330
+ *
1331
+ * Thin wrapper around {@link createOpenAICompatibleProvider} pinned to
1332
+ * OpenRouter's base URL `https://openrouter.ai/api/v1`. Wire shape is
1333
+ * OpenAI Chat Completions; no provider-specific quirks at the
1334
+ * single-shot Promise contract level.
1335
+ *
1336
+ * SECURITY: `apiKey` is a runtime parameter -- do NOT hardcode or log it.
1337
+ *
1338
+ * DEFERRED (D-17 carryforward; Phase 4 ships the named adapter as a
1339
+ * first-class OpenAI-compat wrapper):
1340
+ * - model-routing array -- caller supplies `model` (single id); OpenRouter's
1341
+ * `models: [primary, fallback, ...]` array
1342
+ * feature is deferred to a follow-on phase.
1343
+ * - fallback-array -- deferred (same phase as model-routing).
1344
+ * - per-message routing -- deferred.
1345
+ * - streaming -- deferred (single-shot per CONTEXT.md D-06).
1346
+ * - resume-from-eviction -- see Phase 5 (MV3-survivability adapter).
1347
+ *
1348
+ * Ref: FSB v0.10.0-attempt-2 Phase 4 (D-03: thin wrapper; D-17: model-routing deferred).
1349
+ */
1350
+ interface OpenRouterProviderOptions extends Omit<OpenAICompatibleProviderOptions, "id" | "baseUrl"> {
1351
+ readonly id?: string;
1352
+ /** Defaults to `https://openrouter.ai/api/v1`. Override for proxies. */
1353
+ readonly baseUrl?: string;
1354
+ }
1355
+ declare function createOpenRouterProvider(options: OpenRouterProviderOptions): ProviderAdapter;
1356
+ //#endregion
1357
+ //#region src/providers/xai.d.ts
1358
+ /**
1359
+ * Options for {@link createXaiProvider}.
1360
+ *
1361
+ * Thin wrapper around {@link createOpenAICompatibleProvider} pinned to
1362
+ * xAI's base URL `https://api.x.ai/v1`. The wire shape is identical to
1363
+ * OpenAI Chat Completions, with one provider-specific quirk preserved:
1364
+ * `response.usage.completion_tokens_details.reasoning_tokens` (xAI's
1365
+ * separate reasoning-token accounting; see FSB
1366
+ * `extension/ai/universal-provider.js:585-594` for the production reference).
1367
+ *
1368
+ * SECURITY: `apiKey` is a runtime parameter -- do NOT hardcode or log it.
1369
+ *
1370
+ * DEFERRED (Phase 4 carryforward notes):
1371
+ * - tool-streaming -- deferred
1372
+ * - streaming -- deferred (single-shot Promise per CONTEXT.md D-06)
1373
+ * - resume-from-eviction -- see Phase 5 (MV3-survivability adapter contract)
1374
+ *
1375
+ * Ref: FSB v0.10.0-attempt-2 Phase 4 (D-03 + D-07: thin wrapper; reasoning_tokens quirk preserved).
1376
+ */
1377
+ interface XaiProviderOptions extends Omit<OpenAICompatibleProviderOptions, "id" | "baseUrl"> {
1378
+ readonly id?: string;
1379
+ /** Defaults to `https://api.x.ai/v1`. Override for proxies. */
1380
+ readonly baseUrl?: string;
1381
+ }
1382
+ declare function createXaiProvider(options: XaiProviderOptions): ProviderAdapter;
1383
+ //#endregion
1384
+ //#region src/outputs/infer.d.ts
1385
+ type InferOutput<C> = C extends "text" ? string : C extends StandardSchemaV1 ? StandardSchemaV1.InferOutput<C> : C extends CitationsOutputContract ? readonly CitationRef[] : C extends ArtifactRefsOutputContract ? readonly ArtifactRef[] : never;
1386
+ type InferOutputMap<T extends OutputContractMap> = { readonly [K in keyof T]: InferOutput<T[K]> };
1387
+ //#endregion
1388
+ //#region src/results/result.d.ts
1389
+ interface RunSuccess<TOutputs extends OutputContractMap> {
1390
+ readonly ok: true;
1391
+ readonly outputs: InferOutputMap<TOutputs>;
1392
+ readonly artifacts: readonly ArtifactRef[];
1393
+ readonly usage: Usage;
1394
+ readonly plan: ResultPlan;
1395
+ readonly events?: readonly RunEvent[];
1396
+ /**
1397
+ * Phase 9 — signed capability receipt issued when `LatticeConfig.signer`
1398
+ * is configured. Undefined when no signer is set.
1399
+ */
1400
+ readonly receipt?: ReceiptEnvelope;
1401
+ }
1402
+ interface RunFailure {
1403
+ readonly ok: false;
1404
+ readonly error: LatticeRunError;
1405
+ readonly usage: Usage;
1406
+ readonly raw?: unknown;
1407
+ readonly partialOutputs?: Record<string, unknown>;
1408
+ readonly plan: ResultPlan;
1409
+ readonly events?: readonly RunEvent[];
1410
+ /**
1411
+ * Phase 9 — signed capability receipt issued when `LatticeConfig.signer`
1412
+ * is configured. Undefined when no signer is set.
1413
+ */
1414
+ readonly receipt?: ReceiptEnvelope;
1415
+ }
1416
+ type RunResult<TOutputs extends OutputContractMap> = RunSuccess<TOutputs> | RunFailure;
1417
+ //#endregion
1418
+ //#region src/runtime/survivability.d.ts
1419
+ /**
1420
+ * MV3-survivability adapter contract -- Phase 5 (FSB v0.10.0-attempt-2).
1421
+ *
1422
+ * This module is a SIBLING of create-ai.ts (the Lattice runtime facade) and
1423
+ * a SIBLING of contract/bands.ts (the hook pipeline factory) and
1424
+ * contract/checkpoint.ts (the per-step receipt hook). It does NOT modify
1425
+ * any of them; the SurvivabilityAdapter contract is composed from those
1426
+ * surfaces by the consumer (FSB's lattice-runtime-adapter.js in Plan 05-05).
1427
+ *
1428
+ * What is the survivability problem?
1429
+ * Some host runtimes can evict the execution context mid-flow with no
1430
+ * synchronous shutdown signal:
1431
+ * - Chrome MV3 service workers: evicted after 30s silence OR 5min idle.
1432
+ * - Cloudflare Workers: evicted at end of each request unless waitUntil.
1433
+ * - AWS Lambda: process freeze + thaw across invocations.
1434
+ * Lattice's existing runtime (create-ai.ts) assumes the process stays
1435
+ * live for the duration of a run. The SurvivabilityAdapter contract is
1436
+ * the seam where a host runtime tells Lattice "here is how to serialize
1437
+ * my state, here is how to deserialize it back, here is how to resume
1438
+ * work after I get evicted and recreated."
1439
+ *
1440
+ * What this module SHIPS:
1441
+ * - SurvivabilityAdapter<TState> interface (4 methods)
1442
+ * - SerializedSnapshot type (string-encodable opaque envelope)
1443
+ * - EvictionHook<TState> type (pre-eviction callback signature)
1444
+ * - ResumePolicy literal-union (post-restore reconstruction verdict)
1445
+ * - UnsubscribeFn type
1446
+ * - createNoopSurvivabilityAdapter() reference implementation
1447
+ *
1448
+ * What this module DOES NOT ship:
1449
+ * - chrome.storage.session integration (FSB-side; Plan 05-05).
1450
+ * - offscreen-document message bus (FSB-side; Plan 05-04).
1451
+ * - Auto-wiring into create-ai.ts runtime (deferred indefinitely; the
1452
+ * contract is consumer-controlled).
1453
+ * - Mid-API-request / mid-tool-dispatch recovery dispatcher (CONSERVATIVE
1454
+ * recovery wiring is deferred to a follow-on FSB milestone per
1455
+ * CONTEXT.md D-22; only the ResumePolicy taxonomy lands here).
1456
+ *
1457
+ * Composition conventions (NOT enforced; documented for callers):
1458
+ * D-09: onEviction hooks SHOULD register in BAND.SAFETY band on the
1459
+ * caller's HookPipeline so they run FIRST per Phase 2 priority
1460
+ * ordering. This module does NOT auto-register; it ships the
1461
+ * contract only.
1462
+ * D-10: serialize(state) MAY include the latest checkpoint receipt
1463
+ * envelope (Phase 3 createCheckpointHook output) inside the
1464
+ * SerializedSnapshot.payload; deserialize() reconstructs session
1465
+ * identifiers from the v1.1 receipt body's step-marker fields
1466
+ * (stepName, stepIndex, parentStepName, previousStepName,
1467
+ * sessionId, timestamp). The payload is opaque to Lattice -- the
1468
+ * host runtime defines the shape.
1469
+ *
1470
+ * ResumePolicy taxonomy (CD-E resolution per attempt-1 02-04-PLAN.md):
1471
+ * - SAFE: the snapshot was captured at a safe boundary (BEFORE_ITERATION
1472
+ * or BEFORE_NEXT_ITERATION_SCHEDULE step markers) and can be replayed
1473
+ * deterministically. The host runtime may re-arm the loop.
1474
+ * - RECOVERY_AMBIGUOUS: the snapshot was captured during a tool dispatch
1475
+ * where re-execution risk is non-zero (file write, network POST without
1476
+ * Idempotency-Key, side-effecting browser action). Host should escalate
1477
+ * to the user before deciding.
1478
+ * - ON_ERROR_SW_EVICTION_MID_REQUEST: the eviction happened mid-API-call
1479
+ * (the provider request was in flight). 6 of 7 FSB providers do NOT
1480
+ * document Idempotency-Key headers; replay risks duplicate charges +
1481
+ * duplicate responses. Host should treat the run as failed and surface
1482
+ * the error to the user.
1483
+ * - ON_ERROR_SW_EVICTION_MID_TOOL_DISPATCH: the eviction happened mid-
1484
+ * tool-dispatch (a browser action was in progress). Re-execution risk
1485
+ * is similar to mid-API-call but lands in a different recovery branch
1486
+ * (the host may inspect the page state before deciding).
1487
+ *
1488
+ * SerializedSnapshot is intentionally opaque + string-encodable. The
1489
+ * host runtime defines the payload shape; Lattice's only requirement
1490
+ * is that serialize() followed by deserialize() round-trips the state.
1491
+ *
1492
+ * Ed25519 receipt envelope contract (carries forward from Phase 1-3):
1493
+ * Callers MAY embed a v1.1 ReceiptEnvelope inside SerializedSnapshot.payload
1494
+ * for signed checkpoint round-trip. verifyReceipt against the embedded
1495
+ * envelope MUST return result.ok === true after a serialize -> deserialize
1496
+ * cycle (Test 12). This validates that JSON.stringify + JSON.parse over
1497
+ * the envelope preserves the JCS-canonical body bytes used by DSSE PAE.
1498
+ *
1499
+ * Threat model (Phase 5 CONTEXT.md security block):
1500
+ * - PII via serialized state: callers MUST ensure SerializedSnapshot.payload
1501
+ * contains only stable identifiers + user-controlled state the user has
1502
+ * already consented to persist. Mirrors Phase 2 D-04 receipt-body contract
1503
+ * (step-marker fields are stable identifiers, not free-form user input).
1504
+ * - Snapshot tampering: the noop adapter does NOT sign the snapshot.
1505
+ * Callers that need cryptographic integrity SHOULD embed a signed
1506
+ * ReceiptEnvelope inside the payload + verify it on deserialize.
1507
+ * Phase 5 ships the contract; signature wrapping is a follow-on.
1508
+ *
1509
+ * Vocabulary separation (carries forward Phase 2 D-12 + Phase 3 D-02):
1510
+ * ResumePolicy is the survivability vocabulary -- separate from
1511
+ * RunEventKind (tracing) AND separate from HookLifecycleEvent (bands).
1512
+ * The three vocabularies meet only when a host runtime composes them.
1513
+ */
1514
+ /**
1515
+ * String-encodable opaque snapshot. The host runtime defines the payload
1516
+ * shape; Lattice's only requirement is that serialize() followed by
1517
+ * deserialize() round-trips the original state object.
1518
+ *
1519
+ * Why string-encodable? MV3's chrome.storage.session and most cross-process
1520
+ * storage layers accept structured-clone-safe values. JSON-string payloads
1521
+ * are the lowest-common-denominator that survives MV3 SW eviction +
1522
+ * Cloudflare Worker freeze + Lambda thaw. Callers MAY use a richer payload
1523
+ * shape (Uint8Array, Blob) IF the host runtime supports it; the contract
1524
+ * does not constrain payload format beyond "deserialize round-trips it".
1525
+ */
1526
+ interface SerializedSnapshot {
1527
+ readonly kind: "survivability-snapshot";
1528
+ readonly version: "lattice-survivability/v1";
1529
+ readonly payload: string;
1530
+ readonly capturedAt: string;
1531
+ }
1532
+ /**
1533
+ * Pre-eviction callback. The host runtime CAN attempt to call this hook
1534
+ * before the execution context is evicted, but MAY NOT be able to in
1535
+ * every case (MV3 eviction has no synchronous signal -- the SW just
1536
+ * stops). Callers should treat onEviction as best-effort: useful for
1537
+ * gathering final state when the eviction is announced (e.g., user-
1538
+ * initiated stop) but not load-bearing for involuntary eviction.
1539
+ *
1540
+ * The hook receives the current TState by reference. Mutations on the
1541
+ * hook side leak to the caller's state -- this is deliberate (the hook
1542
+ * is the LAST chance to update state before eviction). Callers who want
1543
+ * structuredClone semantics SHOULD wrap state in their own freeze layer.
1544
+ */
1545
+ type EvictionHook<TState> = (state: TState) => void | Promise<void>;
1546
+ /**
1547
+ * Return value of onEviction(); calling unsubscribes the hook.
1548
+ *
1549
+ * Idempotent -- calling twice has the same effect as calling once.
1550
+ */
1551
+ type UnsubscribeFn = () => void;
1552
+ /**
1553
+ * Resume policy taxonomy. The host runtime calls adapter.resume(snapshot)
1554
+ * after eviction + restore; the returned policy tells the host runtime
1555
+ * how to react.
1556
+ *
1557
+ * The 4 literal members carry forward from FSB v0.10.0-attempt-1's
1558
+ * 02-04-PLAN.md CONSERVATIVE recovery dispatch (preserved at
1559
+ * .planning/milestones/v0.10.0-attempt-1-pre-pivot/02-state-inspectability-
1560
+ * carve-out/02-04-PLAN.md). Per CONTEXT.md CD-E this is the locked union.
1561
+ */
1562
+ type ResumePolicy = "SAFE" | "RECOVERY_AMBIGUOUS" | "ON_ERROR_SW_EVICTION_MID_REQUEST" | "ON_ERROR_SW_EVICTION_MID_TOOL_DISPATCH";
1563
+ /**
1564
+ * The SurvivabilityAdapter contract. Host runtimes implement this; Lattice
1565
+ * runs against the interface.
1566
+ *
1567
+ * 4 methods (D-08 locked):
1568
+ * - serialize(state): convert in-memory state to SerializedSnapshot
1569
+ * - deserialize(snapshot): inverse of serialize
1570
+ * - onEviction(hook): register a best-effort pre-eviction callback
1571
+ * - resume(snapshot): return ResumePolicy verdict for the post-restore
1572
+ * reconstruction. The host runtime acts on the policy.
1573
+ *
1574
+ * Adapters are POLYMORPHIC over TState -- the host runtime parameterizes
1575
+ * the type. Lattice's vitest covers the contract surface with a noop
1576
+ * adapter where TState = Record<string, unknown> for ergonomics.
1577
+ */
1578
+ interface SurvivabilityAdapter<TState> {
1579
+ readonly kind: "survivability-adapter";
1580
+ readonly id: string;
1581
+ serialize(state: TState): SerializedSnapshot;
1582
+ deserialize(snapshot: SerializedSnapshot): TState;
1583
+ onEviction(hook: EvictionHook<TState>): UnsubscribeFn;
1584
+ resume(snapshot: SerializedSnapshot): Promise<ResumePolicy>;
1585
+ }
1586
+ /**
1587
+ * Factory options for the reference noop adapter.
1588
+ *
1589
+ * - id: optional. Defaults to "noop-survivability". Useful when callers
1590
+ * want to distinguish multiple adapter instances in test fixtures.
1591
+ * - policy: optional. Sets the default ResumePolicy returned by resume().
1592
+ * Defaults to "SAFE" (matches noop adapter semantics: no recovery
1593
+ * ambiguity if nothing was ever persisted).
1594
+ */
1595
+ interface NoopSurvivabilityAdapterOptions {
1596
+ readonly id?: string;
1597
+ readonly policy?: ResumePolicy;
1598
+ }
1599
+ /**
1600
+ * Reference implementation of SurvivabilityAdapter<TState>. Records
1601
+ * eviction events but does NOT persist; serialize / deserialize round-
1602
+ * trip via JSON.stringify / JSON.parse. Analog to createFakeProvider
1603
+ * in the providers/ module -- gives Lattice's vitest a complete shape-
1604
+ * conformance target before the real (FSB-side) adapter ships in
1605
+ * Plan 05-05.
1606
+ *
1607
+ * Per CONTEXT.md D-11 the noop adapter ships in Lattice (not FSB)
1608
+ * because it covers the contract surface in Lattice's own test suite;
1609
+ * FSB's real chrome.storage.session-backed adapter is glue layer.
1610
+ */
1611
+ declare function createNoopSurvivabilityAdapter<TState = Record<string, unknown>>(options?: NoopSurvivabilityAdapterOptions): SurvivabilityAdapter<TState>;
1612
+ //#endregion
1613
+ //#region src/tools/tools.d.ts
1614
+ interface ToolExecutionContext {
1615
+ readonly signal?: AbortSignal;
1616
+ readonly emit?: RunEventSink;
1617
+ }
1618
+ interface ToolDefinition<TSchema extends StandardSchemaV1 = StandardSchemaV1> {
1619
+ readonly kind: "tool";
1620
+ readonly name: string;
1621
+ readonly description?: string;
1622
+ readonly inputSchema: TSchema;
1623
+ readonly execute: (input: StandardSchemaV1.InferOutput<TSchema>, context: ToolExecutionContext) => Promise<unknown> | unknown;
1624
+ }
1625
+ interface ToolCallResult {
1626
+ readonly callId: string;
1627
+ readonly toolName: string;
1628
+ readonly artifact: ArtifactInput;
1629
+ }
1630
+ declare function defineTool<TSchema extends StandardSchemaV1>(definition: Omit<ToolDefinition<TSchema>, "kind">): ToolDefinition<TSchema>;
1631
+ declare function runTool<TSchema extends StandardSchemaV1>(tool: ToolDefinition<TSchema>, input: unknown, context?: ToolExecutionContext): Promise<ToolCallResult>;
1632
+ interface McpLikeClient {
1633
+ readonly listTools?: () => Promise<readonly McpToolDescriptor[]> | readonly McpToolDescriptor[];
1634
+ readonly callTool: (input: {
1635
+ readonly name: string;
1636
+ readonly arguments: unknown;
1637
+ }) => Promise<unknown> | unknown;
1638
+ }
1639
+ interface McpToolDescriptor {
1640
+ readonly name: string;
1641
+ readonly description?: string;
1642
+ readonly inputSchema: StandardSchemaV1;
1643
+ }
1644
+ declare function importMcpTools(client: McpLikeClient, toolNames?: readonly string[]): Promise<readonly ToolDefinition[]>;
1645
+ declare function toolArtifactRef(result: ToolCallResult): ArtifactRef;
1646
+ //#endregion
1647
+ //#region src/agent/format-tools.d.ts
1648
+ /**
1649
+ * One turn in the running conversation.
1650
+ *
1651
+ * `role: "tool"` is used for tool-result turns; `toolCallId` and `toolName`
1652
+ * are populated so the model can correlate the result with its prior
1653
+ * `tool_call` envelope.
1654
+ */
1655
+ interface ConversationTurn {
1656
+ readonly role: "user" | "assistant" | "tool";
1657
+ readonly content: string;
1658
+ readonly toolCallId?: string;
1659
+ readonly toolName?: string;
1660
+ }
1661
+ type FormatToolsMode = "native" | "prompt-reencoded" | "auto";
1662
+ interface FormatToolsOptions {
1663
+ /**
1664
+ * Tool-use protocol mode. Defaults to `"auto"`, which currently resolves
1665
+ * to `"prompt-reencoded"` for ALL 7 providers (Phase 19 simplification —
1666
+ * native tool_use deferred to a follow-on milestone). Reserved for
1667
+ * forward compatibility.
1668
+ */
1669
+ readonly mode?: FormatToolsMode;
1670
+ /**
1671
+ * Optional system prompt to prepend. Useful for setting persona /
1672
+ * domain-specific instructions on top of the tool-use envelope.
1673
+ */
1674
+ readonly system?: string;
1675
+ }
1676
+ interface FormattedToolsHandle {
1677
+ /**
1678
+ * Builds the single `task` string passed to `ProviderAdapter.execute()`.
1679
+ * Encodes the conversation, available tools, and response-envelope
1680
+ * instructions.
1681
+ */
1682
+ readonly buildTask: (conversation: readonly ConversationTurn[]) => string;
1683
+ /**
1684
+ * Parses the assistant's response text. Returns:
1685
+ * - `ToolUseRequest[]` when the response contains one or more tool-call
1686
+ * envelopes (parsed in declaration order).
1687
+ * - `null` when the response is a final answer (no tool-call envelopes
1688
+ * detected).
1689
+ *
1690
+ * The parser is forgiving: it tolerates extra prose around the JSON
1691
+ * envelope (markdown fences, leading explanations) and the model
1692
+ * occasionally drifting on whitespace.
1693
+ */
1694
+ readonly parseToolUse: (responseText: string) => ReadonlyArray<ToolUseRequest> | null;
1695
+ /**
1696
+ * Returns the static system block describing available tools. Useful for
1697
+ * tracing / logging the exact tool-description text fed to the model.
1698
+ */
1699
+ readonly describeForSystem: () => string;
1700
+ /**
1701
+ * Effective mode this handle resolved to (`"prompt-reencoded"` for all
1702
+ * v1.2 providers). Exposed for inspectability.
1703
+ */
1704
+ readonly mode: "prompt-reencoded";
1705
+ }
1706
+ /**
1707
+ * Convert a Standard Schema to a JSON Schema-shaped descriptor suitable for
1708
+ * inclusion in an LLM tool description. Standard Schema vendors can
1709
+ * optionally expose `toJSONSchema` on their schema objects; when absent,
1710
+ * we fall back to a minimal structural description that lists the schema
1711
+ * vendor + version + a placeholder. Models tolerate placeholder schemas in
1712
+ * practice because the tool description is supplementary — what matters
1713
+ * is the envelope contract (`{tool_call: {name, args}}`).
1714
+ */
1715
+ declare function toolSchemaToJsonSchema(schema: StandardSchemaV1): unknown;
1716
+ /**
1717
+ * Builds the prompt-reencoded tool-use protocol handle for any provider.
1718
+ *
1719
+ * Phase 19 ships a uniform implementation across all 7 logical providers
1720
+ * (openai, openai-compat, anthropic, gemini, xai, openrouter, lm-studio).
1721
+ * The `providerName` argument is accepted for forward compatibility but
1722
+ * does not branch the implementation in v1.2.
1723
+ */
1724
+ declare function formatToolsForProvider(providerName: string, tools: ReadonlyArray<ToolDefinition<StandardSchemaV1>>, options?: FormatToolsOptions): FormattedToolsHandle;
1725
+ //#endregion
1726
+ //#region src/agent/host.d.ts
1727
+ /**
1728
+ * Snapshot shape the agent loop serializes between iterations. The full
1729
+ * shape is opaque to callers (they only see it through SerializedSnapshot
1730
+ * via the configured SurvivabilityAdapter) but it's exported so reference
1731
+ * implementations and tests can inspect the round-trip.
1732
+ */
1733
+ interface AgentSnapshot {
1734
+ readonly version: "agent-snapshot/v1";
1735
+ readonly iterationIndex: number;
1736
+ readonly conversation: readonly ConversationTurn[];
1737
+ readonly cumulativeUsage: Usage;
1738
+ readonly providerName: string;
1739
+ readonly capturedAt: string;
1740
+ }
1741
+ /**
1742
+ * Scheduler seam — controls how the agent loop yields between iterations.
1743
+ *
1744
+ * `scheduleNext(iterationIndex)` is called AFTER an AFTER_AGENT_ITERATION
1745
+ * emission and BEFORE the next iteration's BEFORE_AGENT_ITERATION. The
1746
+ * scheduler decides when to resume — synchronously (sync loop), on next
1747
+ * tick (setTimeout/queueMicrotask), via a queue (Durable Object), or any
1748
+ * other strategy.
1749
+ *
1750
+ * Default (noop): resolves immediately.
1751
+ */
1752
+ interface AgentScheduler {
1753
+ scheduleNext(iterationIndex: number): Promise<void>;
1754
+ }
1755
+ /**
1756
+ * Transport seam — controls how a provider call is dispatched.
1757
+ *
1758
+ * `call(provider, request)` wraps the provider's `execute()` invocation.
1759
+ * Default (noop): pass-through (`provider.execute!(request)`). Cross-process
1760
+ * bridges (FSB's offscreen-document host) override to dispatch via
1761
+ * `chrome.runtime.sendMessage`.
1762
+ *
1763
+ * Per the Phase 19 INV-03 parity invariant, the transport seam does NOT
1764
+ * modify the `ProviderAdapter` interface — it operates on top of the
1765
+ * existing `execute()` method.
1766
+ */
1767
+ interface AgentTransport {
1768
+ call(provider: ProviderAdapter, request: ProviderRunRequest): Promise<ProviderRunResponse>;
1769
+ }
1770
+ /**
1771
+ * Storage seam — controls how agent state persists between iterations for
1772
+ * resume after host eviction.
1773
+ *
1774
+ * Phase 20 composes this with the Phase 18 `SurvivabilityAdapter`:
1775
+ * - The adapter serializes `AgentSnapshot` to `SerializedSnapshot` on
1776
+ * each AFTER_AGENT_ITERATION; storage.save() persists the snapshot.
1777
+ * - On run start, the agent loop calls storage.load(). If a non-null
1778
+ * snapshot is returned, the adapter deserializes it; the loop resumes
1779
+ * at the recorded iteration index.
1780
+ * - On success, the loop calls storage.clear() so the next run starts
1781
+ * fresh.
1782
+ *
1783
+ * Default (noop): save() is a no-op, load() returns null, clear() is a
1784
+ * no-op. Suitable for Node tests where eviction never occurs.
1785
+ */
1786
+ interface AgentStorage {
1787
+ save(snapshot: SerializedSnapshot): Promise<void>;
1788
+ load(): Promise<SerializedSnapshot | null>;
1789
+ clear(): Promise<void>;
1790
+ }
1791
+ /**
1792
+ * The host adapter — three optional seams, all swappable independently.
1793
+ *
1794
+ * Callers pass `host` on `AgentIntent`. The agent runtime falls back to
1795
+ * `createNoopAgentHost()` when `intent.host` is absent (so Phase 19
1796
+ * single-shot Node usage continues to work without explicit configuration).
1797
+ */
1798
+ interface AgentHost {
1799
+ readonly kind: "agent-host";
1800
+ readonly scheduler?: AgentScheduler;
1801
+ readonly transport?: AgentTransport;
1802
+ readonly storage?: AgentStorage;
1803
+ }
1804
+ /**
1805
+ * Reference implementation suitable for Node tests + the Phase 19 default
1806
+ * behavior.
1807
+ *
1808
+ * - scheduler: resolves immediately (no yield between iterations).
1809
+ * - transport: pass-through to provider.execute().
1810
+ * - storage: save() / clear() are no-ops; load() always returns null.
1811
+ *
1812
+ * Equivalent to passing no host at all.
1813
+ */
1814
+ declare function createNoopAgentHost(): AgentHost;
1815
+ //#endregion
1816
+ //#region src/agent/types.d.ts
1817
+ /**
1818
+ * Per-iteration record stored on `AgentSuccess.iterations` for inspectability.
1819
+ *
1820
+ * `toolCalls` carries content-addressed args/result hashes (sha256) so
1821
+ * downstream receipts can reference them without inlining the bodies.
1822
+ *
1823
+ * `deniedReason` is populated on iterations whose `BEFORE_AGENT_ITERATION`
1824
+ * SAFETY-band handler set `controls.deny(...)`.
1825
+ */
1826
+ interface IterationRecord {
1827
+ readonly index: number;
1828
+ readonly provider: string;
1829
+ readonly promptTokens: number;
1830
+ readonly completionTokens: number;
1831
+ readonly costUsd: number | null;
1832
+ readonly durationMs: number;
1833
+ readonly toolCalls: ReadonlyArray<{
1834
+ readonly id: string;
1835
+ readonly name: string;
1836
+ readonly argsHash: string;
1837
+ readonly resultHash: string;
1838
+ }>;
1839
+ readonly deniedReason?: string;
1840
+ readonly receipt?: ReceiptEnvelope;
1841
+ }
1842
+ /**
1843
+ * Input shape accepted by `ai.runAgent(intent)`.
1844
+ *
1845
+ * All fields except `task` and `tools` are optional. The runtime supplies
1846
+ * sensible defaults (in-process host, fresh pipeline, no signer, no tracer).
1847
+ *
1848
+ * `TOutputs` parameterizes the final-answer schema map; defaults to a free-form
1849
+ * `{ answer: "text" }` shape when the field is omitted. Validation runs once
1850
+ * against the final assistant message (no intermediate iteration validation).
1851
+ */
1852
+ interface AgentIntent<TOutputs extends OutputContractMap = OutputContractMap> {
1853
+ readonly task: string;
1854
+ readonly tools: ReadonlyArray<ToolDefinition<StandardSchemaV1>>;
1855
+ readonly host?: AgentHost;
1856
+ /**
1857
+ * Phase 20 (v1.2): when the agent loop resumes from a host.storage snapshot,
1858
+ * the configured SurvivabilityAdapter handles the serialize/deserialize
1859
+ * round-trip. When absent, runtime defaults to
1860
+ * `createNoopSurvivabilityAdapter<AgentSnapshot>()`.
1861
+ */
1862
+ readonly survivabilityAdapter?: SurvivabilityAdapter<AgentSnapshot>;
1863
+ readonly contract?: CapabilityContract;
1864
+ readonly policy?: PolicySpec;
1865
+ readonly outputs?: TOutputs;
1866
+ readonly pipeline?: HookPipeline;
1867
+ readonly signer?: ReceiptSigner;
1868
+ readonly tracer?: TracerLike;
1869
+ /**
1870
+ * When `false`, the runtime will NOT auto-register `createCheckpointHook`
1871
+ * even if `signer` is provided. Callers who want full manual control over
1872
+ * receipt minting set this to `false` and register their own hook.
1873
+ * Defaults to `true` (auto-register when signer present).
1874
+ */
1875
+ readonly autoRegisterCheckpoint?: boolean;
1876
+ }
1877
+ /**
1878
+ * Success result returned by `ai.runAgent` when the loop reaches a final
1879
+ * answer and (when `outputs` is declared) the final answer validates.
1880
+ *
1881
+ * `iterations[]` records every iteration that ran — including the one that
1882
+ * produced the final answer. `receipt` is the outermost receipt minted at
1883
+ * loop close when `signer` is configured (separate from per-iteration
1884
+ * receipts on `iterations[i].receipt`).
1885
+ */
1886
+ interface AgentSuccess<TOutputs extends OutputContractMap = OutputContractMap> {
1887
+ readonly kind: "success";
1888
+ readonly output: InferOutputMap<TOutputs>;
1889
+ readonly usage: Usage;
1890
+ readonly iterations: ReadonlyArray<IterationRecord>;
1891
+ readonly receipt?: ReceiptEnvelope;
1892
+ }
1893
+ /**
1894
+ * Failure kinds specific to the agent loop. v1.1 `LatticeRunError.kind`
1895
+ * values remain valid (provider errors, no-contract-match, validation-failed,
1896
+ * tripwire-violated) and are reused verbatim. Phase 19 adds three
1897
+ * agent-specific kinds.
1898
+ */
1899
+ type AgentFailureKind = LatticeRunError["kind"] | "agent-iteration-denied" | "agent-max-iterations" | "agent-wall-time-exceeded";
1900
+ /**
1901
+ * Failure result returned by `ai.runAgent`. Discriminates via `kind`.
1902
+ *
1903
+ * `iterations[]` carries any iterations that completed before the failure
1904
+ * (empty if the failure occurred pre-iteration). For `agent-iteration-denied`,
1905
+ * the failing iteration is the LAST entry and carries `deniedReason`.
1906
+ */
1907
+ interface AgentFailure {
1908
+ readonly kind: AgentFailureKind;
1909
+ readonly usage: Usage;
1910
+ readonly iterations: ReadonlyArray<IterationRecord>;
1911
+ readonly reason?: string;
1912
+ readonly cause?: unknown;
1913
+ readonly receipt?: ReceiptEnvelope;
1914
+ }
1915
+ /**
1916
+ * Discriminated union returned by `ai.runAgent`.
1917
+ */
1918
+ type AgentResult<TOutputs extends OutputContractMap = OutputContractMap> = AgentSuccess<TOutputs> | AgentFailure;
1919
+ /**
1920
+ * Typed error raised when a SAFETY-band handler sets `controls.deny(reason)`
1921
+ * during `BEFORE_AGENT_ITERATION`. Carries `terminal: true` semantics to
1922
+ * align with v1.1 `TripwireViolationError`: the failure is NOT retried by
1923
+ * the fallback chain.
1924
+ *
1925
+ * Surfaced via `AgentFailure { kind: "agent-iteration-denied", reason, ... }`
1926
+ * — callers can also catch the typed error if they prefer.
1927
+ */
1928
+ declare class AgentDeniedError extends Error {
1929
+ readonly kind: "agent-iteration-denied";
1930
+ readonly terminal: true;
1931
+ readonly reason: string;
1932
+ readonly iterationIndex: number;
1933
+ constructor(reason: string, iterationIndex: number);
1934
+ }
1935
+ /**
1936
+ * Returned by `formatToolsForProvider` (Phase 19 Plan 19-03). Re-exported
1937
+ * here for convenience; the canonical declaration lives in format-tools.ts.
1938
+ */
1939
+ interface ToolUseRequest {
1940
+ readonly id: string;
1941
+ readonly name: string;
1942
+ readonly args: unknown;
1943
+ }
1944
+ //#endregion
1945
+ //#region src/storage/storage.d.ts
1946
+ interface ArtifactStore {
1947
+ readonly kind: "artifact-store";
1948
+ readonly id: string;
1949
+ put(artifact: ArtifactInput): Promise<ArtifactRef>;
1950
+ get(id: string): Promise<ArtifactRef | undefined>;
1951
+ load(id: string): Promise<ArtifactInput | undefined>;
1952
+ has(id: string): Promise<boolean>;
1953
+ delete(id: string): Promise<boolean>;
1954
+ list(): Promise<readonly ArtifactRef[]>;
1955
+ }
1956
+ type StorageLike = ArtifactStore;
1957
+ interface StoredArtifactPayloadDescriptor {
1958
+ readonly kind: "json" | "binary";
1959
+ readonly path: string;
1960
+ }
1961
+ interface StoredArtifactEnvelope {
1962
+ readonly version: 1;
1963
+ readonly ref: ArtifactRef;
1964
+ readonly payload?: StoredArtifactPayloadDescriptor;
1965
+ }
1966
+ //#endregion
1967
+ //#region src/runtime/config.d.ts
1968
+ interface LatticeConfig {
1969
+ readonly providers?: ProviderRegistryInput;
1970
+ readonly storage?: StorageLike | false;
1971
+ readonly sessions?: SessionStore | false;
1972
+ readonly defaults?: {
1973
+ readonly policy?: PolicySpec;
1974
+ };
1975
+ readonly tracing?: TracerLike | false;
1976
+ readonly events?: RunEventSink | readonly RunEventSink[];
1977
+ /**
1978
+ * Phase 9 — when configured, every terminal branch of `ai.run` emits a
1979
+ * signed `CapabilityReceipt` attached to `RunResult.receipt`. When absent,
1980
+ * no receipts are issued and `RunResult.receipt` is undefined.
1981
+ */
1982
+ readonly signer?: ReceiptSigner;
1983
+ }
1984
+ type NormalizedProviderEntry = ProviderRef | ProviderAdapter;
1985
+ interface NormalizedLatticeConfig {
1986
+ readonly providers: readonly NormalizedProviderEntry[];
1987
+ readonly storage?: StorageLike;
1988
+ readonly sessions?: SessionStore;
1989
+ readonly defaults: {
1990
+ readonly policy?: PolicySpec;
1991
+ };
1992
+ readonly tracing?: TracerLike;
1993
+ readonly events: readonly RunEventSink[];
1994
+ readonly signer?: ReceiptSigner;
1995
+ }
1996
+ //#endregion
1997
+ //#region src/runtime/create-ai.d.ts
1998
+ interface RuntimeOverrides {
1999
+ readonly provider?: string;
2000
+ readonly model?: string;
2001
+ readonly routingPolicy?: PolicySpec;
2002
+ readonly tokenBudget?: number;
2003
+ readonly summarizer?: ContextSummarizer;
2004
+ readonly transforms?: readonly RuntimeArtifactTransform[];
2005
+ readonly hooks?: RuntimeHooks;
2006
+ }
2007
+ interface RuntimeArtifactTransform {
2008
+ readonly name: string;
2009
+ transform(input: {
2010
+ readonly task: string;
2011
+ readonly artifacts: readonly ArtifactInput[];
2012
+ }): Promise<ArtifactInput | readonly ArtifactInput[]> | ArtifactInput | readonly ArtifactInput[];
2013
+ }
2014
+ interface RuntimeHooks {
2015
+ readonly beforeProviderCall?: (input: {
2016
+ readonly plan: ExecutionPlan;
2017
+ readonly request: ProviderRunRequest;
2018
+ }) => void | Promise<void>;
2019
+ readonly afterProviderCall?: (input: {
2020
+ readonly plan: ExecutionPlan;
2021
+ readonly response: unknown;
2022
+ }) => void | Promise<void>;
2023
+ }
2024
+ interface RunIntent<TOutputs extends OutputContractMap> {
2025
+ readonly task: string;
2026
+ readonly artifacts?: readonly ArtifactInput[];
2027
+ readonly outputs: TOutputs;
2028
+ readonly policy?: PolicySpec;
2029
+ readonly session?: SessionRef;
2030
+ readonly signal?: AbortSignal;
2031
+ readonly overrides?: RuntimeOverrides;
2032
+ readonly tools?: readonly ToolDefinition<any>[];
2033
+ readonly toolInputs?: Record<string, unknown>;
2034
+ readonly contract?: CapabilityContract;
2035
+ }
2036
+ interface AI {
2037
+ session(id: string): SessionRef;
2038
+ plan<const TOutputs extends OutputContractMap>(intent: RunIntent<TOutputs>): Promise<ExecutionPlan>;
2039
+ run<const TOutputs extends OutputContractMap>(intent: RunIntent<TOutputs>): Promise<RunResult<TOutputs>>;
2040
+ /**
2041
+ * Phase 19 (v1.2): single-agent execution loop. Drives multiple provider
2042
+ * iterations under one call, dispatching tool requests between iterations.
2043
+ * Composes with the v1.2 hook pipeline (SAFETY-band veto, OBSERVABILITY-band
2044
+ * checkpoint receipts) and the v1.1 capability receipts (when
2045
+ * `intent.signer` is provided + `intent.autoRegisterCheckpoint !== false`).
2046
+ *
2047
+ * See `packages/lattice/src/agent/runtime.ts` for orchestration details.
2048
+ */
2049
+ runAgent<const TOutputs extends OutputContractMap>(intent: AgentIntent<TOutputs>): Promise<AgentResult<TOutputs>>;
2050
+ }
2051
+ declare function createAI(config?: LatticeConfig): AI;
2052
+ //#endregion
2053
+ //#region src/replay/replay.d.ts
2054
+ interface ReplayEnvelope<TOutputs extends OutputContractMap = OutputContractMap> {
2055
+ readonly kind: "replay-envelope";
2056
+ readonly version: 1;
2057
+ readonly runtimeVersion: string;
2058
+ readonly catalogVersion: string;
2059
+ readonly createdAt: string;
2060
+ readonly plan: ExecutionPlan;
2061
+ readonly artifacts: readonly ArtifactRef[];
2062
+ readonly outputs?: InferOutputMap<TOutputs>;
2063
+ readonly warnings: readonly string[];
2064
+ readonly errors: readonly string[];
2065
+ readonly usage?: UsageRecord;
2066
+ readonly events: readonly RunEvent[];
2067
+ /**
2068
+ * Phase 10 — optional signed receipt recorded alongside the envelope so a
2069
+ * single artifact is sufficient to materialize an offline replay session
2070
+ * deterministically. Type-only import — replay.ts stays runtime-import-free
2071
+ * of the receipts builder.
2072
+ */
2073
+ readonly receipt?: ReceiptEnvelope;
2074
+ /**
2075
+ * Phase 10 — optional contract recorded so replays can re-run pre-flight
2076
+ * checks deterministically.
2077
+ */
2078
+ readonly contract?: CapabilityContract;
2079
+ }
2080
+ declare function createReplayEnvelope<TOutputs extends OutputContractMap>(result: RunResult<TOutputs>): ReplayEnvelope<TOutputs>;
2081
+ declare function replayOffline<TOutputs extends OutputContractMap>(envelope: ReplayEnvelope<TOutputs>): Promise<RunResult<TOutputs>>;
2082
+ declare function rerunLive<TOutputs extends OutputContractMap>(ai: AI, envelope: ReplayEnvelope<TOutputs>, intent: RunIntent<TOutputs>): Promise<RunResult<TOutputs>>;
2083
+ declare function redactReplayEnvelope<TOutputs extends OutputContractMap>(envelope: ReplayEnvelope<TOutputs>): ReplayEnvelope<TOutputs>;
2084
+ declare function redactPlan(plan: ExecutionPlan): ExecutionPlan;
2085
+ declare function redactArtifactRef(ref: ArtifactRef): ArtifactRef;
2086
+ //#endregion
2087
+ //#region src/replay/materialize.d.ts
2088
+ /**
2089
+ * Discriminated union of materialization failure modes.
2090
+ *
2091
+ * - "verify-failed" — receipt failed verifyReceipt (signature, key
2092
+ * missing/revoked, canonicalization mismatch).
2093
+ * - "artifact-load-failed" — the artifactLoader callback rejected for at
2094
+ * least one input hash.
2095
+ * - "envelope-malformed" — receipt verified but the verified body is
2096
+ * structurally unusable (should never happen
2097
+ * under verifyReceipt invariants, but kept as a
2098
+ * defensive third branch).
2099
+ */
2100
+ interface MaterializationError {
2101
+ readonly kind: "verify-failed" | "artifact-load-failed" | "envelope-malformed";
2102
+ readonly message: string;
2103
+ }
2104
+ /**
2105
+ * Async callback that resolves an artifact body from its sha256 hex digest.
2106
+ * Phase 10 ships only the in-memory variant for tests. Phase 11's CLI plugs
2107
+ * in a filesystem-backed loader reading from `.lattice/fixtures/<sha256>.bin`.
2108
+ */
2109
+ type ArtifactLoader = (hash: string) => Promise<ArtifactInput>;
2110
+ interface MaterializeReplayEnvelopeOptions<TOutputs extends OutputContractMap = OutputContractMap> {
2111
+ readonly artifactLoader: ArtifactLoader;
2112
+ readonly keySet: KeySet;
2113
+ /** Optional original task string. Defaults to "" when omitted. */
2114
+ readonly task?: string;
2115
+ /**
2116
+ * Optional caller-supplied outputs map. When provided, the resulting
2117
+ * `ReplayEnvelope.outputs` is populated and `replayOffline` will return
2118
+ * an `ok: true` result. When omitted, `replayOffline` reports an
2119
+ * `execution_unavailable` failure (current Phase 5 semantics).
2120
+ */
2121
+ readonly outputs?: InferOutputMap<TOutputs>;
2122
+ readonly policy?: PolicySpec;
2123
+ readonly contract?: CapabilityContract;
2124
+ }
2125
+ /**
2126
+ * Pure async function that reconstructs a `ReplayEnvelope` from a receipt.
2127
+ *
2128
+ * Verify-FIRST ordering: `verifyReceipt` runs before `artifactLoader` is
2129
+ * touched. Tampered receipts MUST NOT cause loader side effects.
2130
+ */
2131
+ declare function materializeReplayEnvelope<TOutputs extends OutputContractMap = OutputContractMap>(receipt: ReceiptEnvelope, options: MaterializeReplayEnvelopeOptions<TOutputs>): Promise<ReplayEnvelope<TOutputs>>;
2132
+ //#endregion
2133
+ //#region src/agent/runtime.d.ts
2134
+ /**
2135
+ * Resolves the runtime's behaviour for a single `ai.runAgent(intent)` call.
2136
+ *
2137
+ * Phase 19 ships an in-process default scheduler (the loop runs in the
2138
+ * calling Promise), direct transport (provider.execute()), and in-memory
2139
+ * transcript (the `conversation` array). Phase 20 promotes scheduler /
2140
+ * transport / storage to the pluggable `AgentHost` adapter.
2141
+ */
2142
+ declare function runAgent<TOutputs extends OutputContractMap = OutputContractMap>(intent: AgentIntent<TOutputs>, config?: LatticeConfig): Promise<AgentResult<TOutputs>>;
2143
+ //#endregion
2144
+ //#region src/agent/infra/cost-tracker.d.ts
2145
+ type CostBudgetStatus = "ok" | "warning" | "exceeded";
2146
+ interface CostTracker {
2147
+ readonly kind: "cost-tracker";
2148
+ /** Append a per-iteration Usage record. Mutates internal state. */
2149
+ recordIteration(usage: Usage): void;
2150
+ /** Returns the running sum across all recorded iterations. */
2151
+ total(): Usage;
2152
+ /**
2153
+ * Reports budget status against `contract.budget`:
2154
+ * - "ok" — under 80% of maxCostUsd.
2155
+ * - "warning" — at or over 80% but under 100%.
2156
+ * - "exceeded" — at or over 100% of maxCostUsd.
2157
+ * Returns "ok" when no budget is declared or when cumulative cost is null.
2158
+ */
2159
+ budgetStatus(budget?: BudgetInvariant): CostBudgetStatus;
2160
+ }
2161
+ declare function createCostTracker(): CostTracker;
2162
+ //#endregion
2163
+ //#region src/agent/infra/transcript-store.d.ts
2164
+ /**
2165
+ * Token estimator used by `tailByTokens`. The default ~4 chars / token is
2166
+ * the OpenAI rule of thumb for English text. Callers with provider-specific
2167
+ * tokenizers can supply their own.
2168
+ */
2169
+ type TokenEstimator = (text: string) => number;
2170
+ interface TranscriptStore {
2171
+ readonly kind: "transcript-store";
2172
+ append(turn: ConversationTurn): void;
2173
+ all(): readonly ConversationTurn[];
2174
+ /** Returns the first user turn (if any) + the most-recent `limit` turns. */
2175
+ tail(limit: number): readonly ConversationTurn[];
2176
+ /**
2177
+ * Returns the first user turn (if any) + the most-recent turns whose
2178
+ * combined token estimate fits within `maxTokens`. The default estimator
2179
+ * is the ~4 chars / token rule; callers can override for provider-
2180
+ * specific tokenizers.
2181
+ */
2182
+ tailByTokens(maxTokens: number, estimator?: TokenEstimator): readonly ConversationTurn[];
2183
+ }
2184
+ declare function createTranscriptStore(): TranscriptStore;
2185
+ //#endregion
2186
+ //#region src/agent/infra/goal-progress.d.ts
2187
+ /**
2188
+ * GoalProgressTracker — Phase 21 (v1.2).
2189
+ *
2190
+ * Stuck-detection primitive. The caller declares a goal-satisfaction
2191
+ * score per iteration (0..1); the tracker reports a coarse status the
2192
+ * agent loop can use to back off or surface to the human.
2193
+ */
2194
+ type ProgressStatus = "progressing" | "stalled" | "regressed";
2195
+ interface GoalProgressOptions {
2196
+ /**
2197
+ * Window of recent steps used for stall + regression detection.
2198
+ * Default 3. The tracker waits until it has at least this many steps
2199
+ * before reporting anything other than "progressing".
2200
+ */
2201
+ readonly windowSize?: number;
2202
+ /** Max satisfaction delta across the window to count as "stalled". Default 0.02. */
2203
+ readonly stallThreshold?: number;
2204
+ /** Min drop from prior max to count as "regressed". Default 0.1. */
2205
+ readonly regressionThreshold?: number;
2206
+ }
2207
+ interface GoalProgressStep {
2208
+ readonly iterationIndex: number;
2209
+ readonly goalSatisfaction: number;
2210
+ }
2211
+ interface GoalProgressTracker {
2212
+ readonly kind: "goal-progress-tracker";
2213
+ recordStep(step: GoalProgressStep): void;
2214
+ status(): ProgressStatus;
2215
+ }
2216
+ declare function createGoalProgressTracker(options?: GoalProgressOptions): GoalProgressTracker;
2217
+ //#endregion
2218
+ //#region src/agent/infra/action-history.d.ts
2219
+ /**
2220
+ * ActionHistory — Phase 21 (v1.2).
2221
+ *
2222
+ * Detects stuck patterns in the agent loop's tool-call sequence:
2223
+ * - "consecutive-identical-tool-call" — same (toolName, argsHash) N+ times in a row
2224
+ * - "ping-pong" — last 4 records alternate between 2 distinct (toolName, argsHash) pairs
2225
+ * - "no-progress" — reserved for callers wiring goal-progress feedback here
2226
+ *
2227
+ * Standalone (no dependency on the agent runtime); callers register the
2228
+ * primitive externally and pump `recordAction` from their loop or hook.
2229
+ */
2230
+ declare const STUCK_REASONS: readonly ["consecutive-identical-tool-call", "no-progress", "ping-pong"];
2231
+ type StuckReason = typeof STUCK_REASONS[number];
2232
+ interface ActionRecord {
2233
+ readonly iterationIndex: number;
2234
+ readonly toolName: string;
2235
+ readonly argsHash: string;
2236
+ }
2237
+ interface ActionHistoryOptions {
2238
+ /** Number of consecutive identical records that triggers the consecutive detector. Default 3. */
2239
+ readonly consecutiveLimit?: number;
2240
+ }
2241
+ interface ActionHistory {
2242
+ readonly kind: "action-history";
2243
+ /**
2244
+ * Append a record. Returns the latest StuckReason triggered by this
2245
+ * record, or null when no detector fires. The most recent reason wins
2246
+ * when multiple apply.
2247
+ */
2248
+ recordAction(action: ActionRecord): StuckReason | null;
2249
+ history(): readonly ActionRecord[];
2250
+ }
2251
+ declare function createActionHistory(options?: ActionHistoryOptions): ActionHistory;
2252
+ //#endregion
2253
+ //#region src/agent/infra/permission-context.d.ts
2254
+ interface PermissionRule {
2255
+ /** Match on tool name. String = exact match; RegExp = test. Both undefined = match-any. */
2256
+ readonly toolName?: string | RegExp;
2257
+ /**
2258
+ * Optional resource matcher. The caller passes `resource` on each
2259
+ * decide() invocation; this rule fires only when the rule's resource
2260
+ * matches.
2261
+ */
2262
+ readonly resource?: string | RegExp;
2263
+ readonly verdict: "allow" | "deny";
2264
+ readonly reason?: string;
2265
+ }
2266
+ interface PermissionDecisionInput {
2267
+ readonly toolName: string;
2268
+ readonly iterationIndex: number;
2269
+ readonly resource?: string;
2270
+ readonly args?: unknown;
2271
+ }
2272
+ type PermissionVerdict = {
2273
+ readonly allow: true;
2274
+ } | {
2275
+ readonly allow: false;
2276
+ readonly reason: string;
2277
+ };
2278
+ interface PermissionContext {
2279
+ readonly kind: "permission-context";
2280
+ decide(input: PermissionDecisionInput): PermissionVerdict;
2281
+ }
2282
+ declare function createPermissionContext(rules: readonly PermissionRule[]): PermissionContext;
2283
+ /**
2284
+ * Hook handler shape suitable for registering on `BEFORE_TOOL` at
2285
+ * BAND.SAFETY. Reads `toolName` and `iterationIndex` from the agent
2286
+ * runtime's BEFORE_TOOL context shape (`{ iterationIndex, toolName,
2287
+ * args }`) and translates a deny verdict into `controls.deny(reason)`.
2288
+ */
2289
+ interface PermissionHookContext {
2290
+ readonly iterationIndex: number;
2291
+ readonly toolName: string;
2292
+ readonly resource?: string;
2293
+ readonly args?: unknown;
2294
+ }
2295
+ declare function createPermissionGuardHook(context: PermissionContext): HookHandler<PermissionHookContext>;
2296
+ /**
2297
+ * Convenience: returns RegisterOptions for the SAFETY-band registration.
2298
+ * Callers do `pipeline.register("BEFORE_TOOL", hook, permissionGuardRegisterOptions())`.
2299
+ */
2300
+ declare function permissionGuardRegisterOptions(): RegisterOptions;
2301
+ //#endregion
2302
+ //#region src/agent/eval.d.ts
2303
+ /**
2304
+ * Summary of an agent run sufficient for regression analysis. Callers
2305
+ * typically derive this from an `AgentSuccess` via `iterations.length` and
2306
+ * cumulative `usage`. The schema is intentionally minimal so callers can
2307
+ * persist + load it across runs without dragging the full ReplayEnvelope.
2308
+ */
2309
+ interface AgentRunSnapshot {
2310
+ readonly iterationsToGoal: number;
2311
+ readonly usage: Usage;
2312
+ }
2313
+ interface EvalOptions {
2314
+ /**
2315
+ * Maximum tolerated INCREASE in iterations-to-goal versus the baseline.
2316
+ * Default 1 (one extra iteration tolerated). Set to 0 to require parity.
2317
+ */
2318
+ readonly iterationsToGoalRegressionLimit?: number;
2319
+ /**
2320
+ * Maximum tolerated FRACTIONAL cost increase versus the baseline.
2321
+ * Default 0.10 (10% increase tolerated). Compared as
2322
+ * `(current - baseline) / baseline`. Cost regressions are only
2323
+ * considered when BOTH snapshots have a non-null `costUsd`; mixed-cost
2324
+ * snapshots emit a `mixed-cost-unknown` regression so callers can decide
2325
+ * how to handle them.
2326
+ */
2327
+ readonly costUsdRegressionLimit?: number;
2328
+ }
2329
+ type EvalRegressionKind = "iterations-to-goal" | "cost-regression" | "mixed-cost-unknown";
2330
+ interface EvalRegression {
2331
+ readonly kind: EvalRegressionKind;
2332
+ readonly baseline: number | null;
2333
+ readonly current: number | null;
2334
+ readonly limit: number;
2335
+ readonly message: string;
2336
+ }
2337
+ interface AgentEvalResult {
2338
+ readonly ok: boolean;
2339
+ readonly regressions: ReadonlyArray<EvalRegression>;
2340
+ }
2341
+ declare function evalAgentRun(baseline: AgentRunSnapshot, current: AgentRunSnapshot, options?: EvalOptions): AgentEvalResult;
2342
+ //#endregion
2343
+ //#region src/storage/local.d.ts
2344
+ interface LocalArtifactStoreOptions {
2345
+ readonly id?: string;
2346
+ }
2347
+ declare function createLocalArtifactStore(rootDir: string | URL, options?: LocalArtifactStoreOptions): ArtifactStore;
2348
+ //#endregion
2349
+ //#region src/storage/memory.d.ts
2350
+ interface MemoryArtifactStoreOptions {
2351
+ readonly id?: string;
2352
+ }
2353
+ declare function createMemoryArtifactStore(options?: MemoryArtifactStoreOptions): ArtifactStore;
2354
+ //#endregion
2355
+ //#region src/version.d.ts
2356
+ declare const latticeVersion = "0.0.0";
2357
+ //#endregion
2358
+ export { type AI, type ActionHistory, type ActionHistoryOptions, type ActionRecord, AgentDeniedError, type AgentEvalResult, type AgentFailure, type AgentFailureKind, type AgentHost, type AgentIntent, type AgentResult, type AgentRunSnapshot, type AgentScheduler, type AgentSnapshot, type AgentStorage, type AgentSuccess, type AgentTransport, type AnthropicProviderOptions, type ArtifactFingerprint, type ArtifactInput, type ArtifactKind, type ArtifactLineage, type ArtifactOptions, type ArtifactParentRef, type ArtifactPrivacy, type ArtifactRef, type ArtifactSize, type ArtifactSource, type ArtifactStorageRef, type ArtifactStore, type ArtifactTransformDescriptor, type ArtifactTransformKind, BAND, type BudgetInvariant, type CapabilityContract, type CapabilityContractInput, type CapabilityReceiptBody, type CheckpointHookContext, type CheckpointHookOptions, type ContractRejectReasonCode, type ContractVerdict, type ConversationTurn, type CostBudgetStatus, type CostTracker, type CreateReceiptInput, DEFAULT_CHECKPOINT_BAND, type EvalOptions, type EvalRegression, type EvalRegressionKind, type EvictionHook, type ExecutionPlanStub, type FieldFromTableInvariant, type FormatToolsMode, type FormatToolsOptions, type FormattedToolsHandle, type GeminiProviderOptions, type GoalProgressOptions, type GoalProgressStep, type GoalProgressTracker, type HookControls, type HookDenyDirective, type HookLifecycleEvent, type HookPipeline, type InferOutput, type InferOutputMap, type InvariantDeclaration, type InvariantOptions, type IterationRecord, type KeyEntry, type KeySet, type KeyState, type LatticeConfig, type LatticeRunError, type LmStudioProviderOptions, type MatchesInvariant, type MaterializationError, type MaterializeReplayEnvelopeOptions, type MustCiteInvariant, type NoPiiInvariant, type NormalizedLatticeConfig, type OpenRouterProviderOptions, type OutputContract, type OutputContractMap, type PermissionContext, type PermissionDecisionInput, type PermissionHookContext, type PermissionRule, type PermissionVerdict, type PiiDetector, type PiiDetectorResult, type PolicySpec, type ProgressStatus, type ProviderAdapter, type ProviderRef, type ProviderRunRequest, type ProviderRunResponse, type QualityFloorInvariant, type ReceiptEnvelope, type ReceiptModel, type ReceiptRedaction, type ReceiptRoute, type ReceiptSignature, type ReceiptSigner, type ReceiptUsageCanonical, type ReplayEnvelope, type ResumePolicy, type RunFailure, type RunIntent, type RunResult, type RunSuccess, STEP_TRANSITION_EVENT_NAME, STUCK_REASONS, type SerializedSnapshot, type SessionRef, type StorageLike, type StoredArtifactEnvelope, type StoredArtifactPayloadDescriptor, type StuckReason, type SurvivabilityAdapter, type TokenEstimator, type ToolUseRequest, type TracerLike, type TranscriptStore, type TripwireEvidence, type TripwireResult, type TripwireViolationError, type UnsubscribeFn, type Usage, type ValidationIssue, type VerifyError, type VerifyErrorKind, type VerifyFail, type VerifyOk, type VerifyResult, type XaiProviderOptions, artifact, contract, createAI, createAISdkProvider, createActionHistory, createAnthropicProvider, createCheckpointHook, createCostTracker, createFakeProvider, createGeminiProvider, createGoalProgressTracker, createHookPipeline, createInMemorySigner, createLmStudioProvider, createLocalArtifactStore, createMemoryArtifactStore, createMemoryKeySet, createMemorySessionStore, createNoopAgentHost, createNoopSurvivabilityAdapter, createOpenAICompatibleProvider, createOpenAIProvider, createOpenRouterProvider, createPermissionContext, createPermissionGuardHook, createReceipt, createReplayEnvelope, createTranscriptStore, createXaiProvider, defaultPiiDetectors, defineTool, estimateRouteCost, evalAgentRun, evaluateContractAgainstRoute, evaluateTripwires, formatToolsForProvider, generateEd25519KeyPairJwk, importMcpTools, inv, isTerminal, latticeVersion, materializeReplayEnvelope, output, permissionGuardRegisterOptions, redactArtifactRef, redactPlan, redactReplayEnvelope, replayOffline, rerunLive, runAgent, runTool, toolArtifactRef, toolSchemaToJsonSchema, verifyReceipt };
2359
+ //# sourceMappingURL=index.d.ts.map