verdifax 0.2.11 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -1,3 +1,5 @@
1
+ import { KeyObject } from 'node:crypto';
2
+
1
3
  /**
2
4
  * Type definitions for the Verdifax orchestrator REST API.
3
5
  *
@@ -46,8 +48,74 @@ interface ExecuteRequest {
46
48
  registry_record_hash: Hex64;
47
49
  /** When non-empty, opts the request into the AIVP governance pipeline. */
48
50
  ai_output_text?: string;
49
- /** Caller-attested actor + decision metadata; open schema. */
51
+ /** Caller-attested actor + decision metadata; open schema. The client
52
+ * derives `attested` from whether any other field is provided. */
50
53
  attested_context?: Record<string, unknown>;
54
+ /** Caller-declared runtime fingerprint, recorded in the audit bundle.
55
+ * Build it with {@link captureEnvironment}. */
56
+ reproducibility_context?: ReproducibilityContext;
57
+ /** Caller-supplied substance of the request: prompt, output, cost,
58
+ * latency and origin metadata. Recorded as supplied. Leave out
59
+ * `origin.source_ip_hash` and `origin.user_agent_hash`: the server
60
+ * computes those and refuses them. */
61
+ request_substance?: Record<string, unknown>;
62
+ /** Caller-supplied approval chain. Recorded as supplied, not verified
63
+ * by Verdifax. */
64
+ authorization_chain?: Record<string, unknown>;
65
+ /** Caller-supplied regulatory metadata. Recorded as supplied, not an
66
+ * assessment by Verdifax. */
67
+ regulatory_scaffolding?: Record<string, unknown>;
68
+ /** Caller-supplied record of what led to this run. Recorded as
69
+ * supplied. */
70
+ causal_graph?: Record<string, unknown>;
71
+ /** Filled in by the client when the `signingKey` option is set. */
72
+ request_signature?: RequestSignature;
73
+ }
74
+ /** The runtime a caller declares for a run. Every field is optional.
75
+ * The server records these values as given and does not check them. */
76
+ interface ReproducibilityContext {
77
+ /** True when any other field has a value. The client derives this. */
78
+ declared?: boolean;
79
+ /** 64 hex characters, without the `sha256:` prefix. */
80
+ container_image_hash?: string;
81
+ runtime_name?: string;
82
+ runtime_version?: string;
83
+ /** `name==version` strings, sorted. */
84
+ pinned_dependencies?: string[];
85
+ git_commit_sha?: string;
86
+ /** `library=seed` strings, sorted. */
87
+ random_seeds?: string[];
88
+ /** GOOS/GOARCH style, for example `linux/amd64`. */
89
+ platform?: string;
90
+ }
91
+ /** The signature an API key with a registered request key must carry.
92
+ * The public key comes from the registration, never from the request. */
93
+ interface RequestSignature {
94
+ /** Base64 Ed25519 signature. */
95
+ signature: string;
96
+ /** RFC 3339 UTC with whole seconds, for example 2026-11-05T02:18:00Z. */
97
+ signed_at: string;
98
+ /** 16 random bytes as 32 lowercase hex characters, fresh per request. */
99
+ nonce: string;
100
+ }
101
+ /** A key pair from {@link generateRequestKeyPair}, as raw bytes. */
102
+ interface RequestKeyPair {
103
+ /** The 32-byte Ed25519 public key. */
104
+ publicKey: Buffer;
105
+ /** The 32-byte Ed25519 private key. Keep it secret. */
106
+ privateKey: Buffer;
107
+ }
108
+ /** Body of POST /keys/request-key. */
109
+ interface RequestKeyRegistrationBody {
110
+ /** Base64 of the raw 32-byte public key. */
111
+ public_key: string;
112
+ /** Base64 signature proving the caller holds the private key. */
113
+ proof: string;
114
+ }
115
+ /** Returned by {@link VerdifaxClient.registerRequestKey}. */
116
+ interface RequestKeyRegistration {
117
+ ok: boolean;
118
+ public_key: string;
51
119
  }
52
120
  interface ExecuteResponse {
53
121
  ok: boolean;
@@ -55,6 +123,60 @@ interface ExecuteResponse {
55
123
  manifest: ExecutionManifest;
56
124
  duration_ms: number;
57
125
  }
126
+ /** One row of {@link ExecuteBatchResponse}. A successful row has
127
+ * `manifest`. A failed row has `error`, and `error_stage` and a typed
128
+ * receipt when the pipeline halted. A row refused before it ran has
129
+ * no `run_id`. */
130
+ interface ExecuteBatchResult {
131
+ index: number;
132
+ ok: boolean;
133
+ run_id?: number;
134
+ manifest_hash?: Hex64;
135
+ manifest?: ExecutionManifest;
136
+ error?: string;
137
+ error_stage?: string;
138
+ duration_ms: number;
139
+ partial_manifest?: ExecutionManifest;
140
+ deny_receipt?: Record<string, unknown>;
141
+ ccv_halt_receipt?: Record<string, unknown>;
142
+ macc_halt_receipt?: Record<string, unknown>;
143
+ aivp_t4_halt_receipt?: Record<string, unknown>;
144
+ attestation_gap_receipt?: Record<string, unknown>;
145
+ }
146
+ /** Body returned by POST /execute/batch. */
147
+ interface ExecuteBatchResponse {
148
+ ok: boolean;
149
+ total: number;
150
+ successful: number;
151
+ failed: number;
152
+ duration_ms: number;
153
+ results: ExecuteBatchResult[];
154
+ }
155
+ /** One of the two runs of a determinism check. */
156
+ interface DeterminismRun {
157
+ run_id: number;
158
+ manifest_hash: string;
159
+ bundle_hash: string;
160
+ duration_ms: number;
161
+ status: string;
162
+ error?: string;
163
+ }
164
+ /** How the two runs of a determinism check compared. */
165
+ interface DeterminismDiff {
166
+ differs: boolean;
167
+ manifest_hash_differs: boolean;
168
+ bundle_hash_differs: boolean;
169
+ differing_fields?: string[];
170
+ }
171
+ /** Body returned by POST /execute/verify-determinism. `deterministic`
172
+ * means both runs ended ok with equal manifest hashes. */
173
+ interface VerifyDeterminismResponse {
174
+ ok: boolean;
175
+ deterministic: boolean;
176
+ first: DeterminismRun;
177
+ second: DeterminismRun;
178
+ diff: DeterminismDiff;
179
+ }
58
180
  /**
59
181
  * Sealed manifest. Field names match the orchestrator's Go-default
60
182
  * JSON encoding (CapitalCamelCase).
@@ -88,6 +210,12 @@ interface ExecutionManifest {
88
210
  LedgerProofHash?: Hex64;
89
211
  LogEntryID?: string;
90
212
  }
213
+ /** Every status the server gives a run. */
214
+ declare const RUN_STATUSES: readonly ["ok", "probe", "pepg_deny", "ccv_halt", "macc_halt", "aivp_t4_halt", "attestation_gap", "stage_error"];
215
+ /** A run's status: one of {@link RUN_STATUSES}, or a value a newer server
216
+ * adds. Written with `string & {}` so editors still offer the known
217
+ * values and any string can be compared. */
218
+ type RunStatus = (typeof RUN_STATUSES)[number] | (string & {});
91
219
  interface Run {
92
220
  ok: boolean;
93
221
  id: number;
@@ -97,7 +225,7 @@ interface Run {
97
225
  route_id: string;
98
226
  manifest_hash: Hex64;
99
227
  duration_ms: number;
100
- status: "ok" | "pepg_deny" | "ccv_halt" | "macc_halt" | "stage_error";
228
+ status: RunStatus;
101
229
  error_stage?: string;
102
230
  error_message?: string;
103
231
  manifest: ExecutionManifest;
@@ -132,6 +260,10 @@ interface ClientConfig {
132
260
  * it on each subsequent retry (exponential backoff with full
133
261
  * jitter). Defaults to 200ms. */
134
262
  retryBaseDelayMs?: number;
263
+ /** The 32 raw bytes of an Ed25519 private key. When set, every path to
264
+ * POST /execute signs its request. The key is never sent to the
265
+ * server. Leave unset for unsigned requests. */
266
+ signingKey?: Uint8Array;
135
267
  }
136
268
  /** Friendly shape for {@link VerdifaxClient.attest}. Mirrors the
137
269
  * Python SDK's `attest()` signature so polyglot teams have parity. */
@@ -147,6 +279,11 @@ interface AttestRequest {
147
279
  registry_record_hash: Hex64;
148
280
  ai_output_text?: string;
149
281
  attested_context?: Record<string, unknown>;
282
+ reproducibility_context?: ReproducibilityContext;
283
+ request_substance?: Record<string, unknown>;
284
+ authorization_chain?: Record<string, unknown>;
285
+ regulatory_scaffolding?: Record<string, unknown>;
286
+ causal_graph?: Record<string, unknown>;
150
287
  }
151
288
  /** Optional filters for {@link VerdifaxClient.listRuns}. */
152
289
  interface ListRunsParams {
@@ -162,8 +299,94 @@ interface RunSummary {
162
299
  program_id: Hex64;
163
300
  route_id: string;
164
301
  manifest_hash: Hex64;
165
- status: "ok" | "pepg_deny" | "ccv_halt" | "macc_halt" | "stage_error";
302
+ status: RunStatus;
166
303
  outcome_kind?: string;
304
+ duration_ms?: number;
305
+ error_stage?: string;
306
+ execution_region?: string;
307
+ }
308
+ /** Optional filters for {@link VerdifaxClient.searchRuns}. `from` and
309
+ * `to` are RFC 3339 times. */
310
+ interface SearchRunsParams {
311
+ /** Matches manifest hashes that start with this value. */
312
+ manifest_hash?: string;
313
+ program_id?: Hex64;
314
+ route_id?: string;
315
+ status?: string;
316
+ from?: string;
317
+ to?: string;
318
+ limit?: number;
319
+ offset?: number;
320
+ }
321
+ /** Period for {@link VerdifaxClient.exportRuns} and
322
+ * {@link VerdifaxClient.exportRunsCSV}, as RFC 3339 times. `from` is
323
+ * inclusive and `to` is exclusive. `to` defaults to the time of the
324
+ * request. */
325
+ interface ExportRunsParams {
326
+ from?: string;
327
+ to?: string;
328
+ }
329
+ /** One run in an evidence export: what the server stored, not a verdict. */
330
+ interface ExportRow {
331
+ run_id: number;
332
+ created_at: string;
333
+ status: RunStatus;
334
+ error_stage: string;
335
+ route_id: string;
336
+ manifest_hash: string;
337
+ log_entry_id: string;
338
+ leaf_hash: string;
339
+ complete_record_entry_id: string;
340
+ complete_record_leaf_hash: string;
341
+ }
342
+ /** Body returned by GET /runs/export in JSON form. */
343
+ interface RunsExport {
344
+ ok: boolean;
345
+ /** The upper bound the server used for this export. */
346
+ to: string;
347
+ /** Runs held for the period. */
348
+ total: number;
349
+ /** Rows in this response. */
350
+ returned: number;
351
+ /** True when the period holds more rows than this response. */
352
+ truncated: boolean;
353
+ /** Rows returned, counted by status. */
354
+ by_status: Record<string, number>;
355
+ runs: ExportRow[];
356
+ }
357
+ /** Returned by {@link VerdifaxClient.exportRunsCSV}. */
358
+ interface RunsExportCSV {
359
+ /** The CSV text, unparsed. */
360
+ csv: string;
361
+ /** Runs held for the period. */
362
+ total: number;
363
+ /** True when the period holds more rows than `csv`. */
364
+ truncated: boolean;
365
+ }
366
+ /** Optional paging for {@link VerdifaxClient.listAttestations}. */
367
+ interface ListAttestationsParams {
368
+ limit?: number;
369
+ offset?: number;
370
+ }
371
+ /** Body returned by GET /attestations. Each row is a receipt as the
372
+ * server sends it, without its inclusion proof. */
373
+ interface AttestationList {
374
+ ok: boolean;
375
+ count: number;
376
+ limit: number;
377
+ offset: number;
378
+ attestations: Record<string, unknown>[];
379
+ }
380
+ /** Body returned by GET /stats. */
381
+ interface RunStats {
382
+ ok: boolean;
383
+ total_runs: number;
384
+ runs_today: number;
385
+ runs_last_24h: number;
386
+ pass_rate: number;
387
+ avg_duration_ms: number;
388
+ last_run_at: string;
389
+ runs_by_program: Record<string, number>;
167
390
  }
168
391
  /** Audit-PDF format selector. */
169
392
  type PDFFormat = "brief" | "auditor" | "legal" | "comprehensive";
@@ -230,6 +453,8 @@ interface AdminAPIKey {
230
453
  revoked: boolean;
231
454
  }
232
455
 
456
+ /** The most rows POST /execute/batch accepts in one request. */
457
+ declare const MAX_BATCH_ROWS = 1000;
233
458
  /**
234
459
  * The Verdifax SDK client.
235
460
  *
@@ -239,17 +464,32 @@ interface AdminAPIKey {
239
464
  * | --- | --- | --- |
240
465
  * | `health()` | GET /health | none |
241
466
  * | `version()` | GET /version | none |
467
+ * | `getOpenAPI()` | GET /openapi.json | none |
468
+ * | `getStats()` | GET /stats | required |
242
469
  * | `execute(req)` | POST /execute | required |
243
470
  * | `attest(req)` | POST /execute (helper) | required |
244
471
  * | `getRun(id)` | GET /runs/{id} | required |
245
472
  * | `verifyRun(id)` | GET /runs/{id}/verify | required |
246
473
  * | `listRuns(params)` | GET /runs | required |
474
+ * | `searchRuns(params)` | GET /runs/search | required |
475
+ * | `exportRuns(params)` | GET /runs/export | required |
476
+ * | `exportRunsCSV(params)` | GET /runs/export?format=csv | required |
477
+ * | `listAttestations(params)` | GET /attestations | required |
478
+ * | `getAttestation(id)` | GET /attestations/{id} | required |
479
+ * | `getRunArtifacts(id)` | GET /runs/{id}/artifacts | required |
480
+ * | `getRunReport(id)` | GET /runs/{id}/report | required |
481
+ * | `getPublicBundle(id)` | GET /runs/{id}/bundle.json | none |
482
+ * | `getPublicBundleByToken(token)` | GET /public/runs/{token}/bundle.json | none |
483
+ * | `executeBatch(runs)` | POST /execute/batch | required |
484
+ * | `verifyDeterminism(req)` | POST /execute/verify-determinism | required |
247
485
  * | `downloadAuditPDF(id, format)` | GET /runs/{id}/report.pdf | required |
248
486
  * | `getAllowToken(id)` | GET /runs/{id}/allow-token | required |
249
487
  * | `getDenyReceipt(id)` | GET /runs/{id}/deny-receipt | required |
250
488
  * | `getCCVHaltReceipt(id)` | GET /runs/{id}/ccv-halt-receipt | required |
251
489
  * | `getMACCHaltReceipt(id)` | GET /runs/{id}/macc-halt-receipt | required |
252
490
  * | `getAivpT4HaltReceipt(id)` | GET /runs/{id}/aivp-t4-halt-receipt | required |
491
+ * | `getAttestationGapReceipt(id)` | GET /runs/{id}/attestation-gap-receipt | required |
492
+ * | `getCESAuditRecord(id)` | GET /runs/{id}/ces-audit-record | required |
253
493
  * | `listDeletionReceipts(id)` | GET /runs/{id}/deletion-receipts | required |
254
494
  * | `adminErase(req)` | POST /admin/erase | required |
255
495
  * | `dcaeVerify(bundle)` | POST /dcae/verify | none |
@@ -258,6 +498,12 @@ interface AdminAPIKey {
258
498
  * | `adminRevokeKey(id)` | DELETE /admin/keys/{id} | required |
259
499
  * | `attestClaudeResponse(...)` | POST /execute (helper) | required |
260
500
  * | `attestOpenAIResponse(...)` | POST /execute (helper) | required |
501
+ * | `registerRequestKey()` | POST /keys/request-key | required |
502
+ * | `clearRequestKey()` | DELETE /keys/request-key | required |
503
+ *
504
+ * With the `signingKey` option set, every path to POST /execute carries
505
+ * a fresh request signature, each row of a batch carries its own, and a
506
+ * determinism check carries one. Without it, requests are unsigned.
261
507
  *
262
508
  * Idempotent GETs that hit a transient failure (502/503/504/429)
263
509
  * are retried with exponential backoff + full jitter. Non-
@@ -271,26 +517,87 @@ declare class VerdifaxClient {
271
517
  private readonly userAgent;
272
518
  private readonly maxRetries;
273
519
  private readonly retryBaseDelayMs;
520
+ private readonly signingKey;
274
521
  constructor(config?: ClientConfig);
275
522
  health(): Promise<Health>;
276
523
  version(): Promise<VerdifaxVersion>;
524
+ /** The server's own API description. */
525
+ getOpenAPI(): Promise<Record<string, unknown>>;
526
+ /** Run counts for this API key. */
527
+ getStats(): Promise<RunStats>;
277
528
  execute(req: ExecuteRequest): Promise<ExecuteResponse>;
529
+ /** Runs one payload twice on the server and compares the manifest
530
+ * hashes. One signature covers the request, and the server claims
531
+ * its nonce once. Both runs are recorded. */
532
+ verifyDeterminism(req: ExecuteRequest): Promise<VerifyDeterminismResponse>;
533
+ /** Sends up to {@link MAX_BATCH_ROWS} runs in one request. With a
534
+ * signing key each row carries its own signature and nonce. A row
535
+ * that fails comes back in `results` with `ok: false`, so the call
536
+ * does not throw for it. The rows are not checked here: the server
537
+ * reports a bad row in that row's result.
538
+ *
539
+ * This is one POST and it is never retried. After a timeout the
540
+ * server may have run some or all of the rows. */
541
+ executeBatch(runs: ExecuteRequest[]): Promise<ExecuteBatchResponse>;
278
542
  /** High-level convenience wrapper around `execute()`. Accepts
279
543
  * either a Buffer (for binary payloads, auto-base64) or a
280
544
  * string (for plain text). Validates the hex fields and
281
545
  * routes the call through to the canonical /execute. */
282
546
  attest(req: AttestRequest): Promise<ExecuteResponse>;
547
+ /** Registers this client's public key on its API key, with the proof
548
+ * that the client holds the private key. From then on the server
549
+ * refuses a run on this API key without a request signature. */
550
+ registerRequestKey(): Promise<RequestKeyRegistration>;
551
+ /** Clears the registered public key, so the server stops requiring
552
+ * request signatures on this API key. */
553
+ clearRequestKey(): Promise<void>;
283
554
  getRun(runId: number): Promise<Run>;
284
555
  verifyRun(runId: number): Promise<VerifyResponse>;
285
556
  listRuns(params?: ListRunsParams): Promise<{
286
557
  runs: RunSummary[];
287
558
  total: number;
288
559
  }>;
560
+ /** Searches this key's runs. `manifest_hash` matches a prefix. The
561
+ * server ignores a `from` or `to` it cannot parse here, unlike
562
+ * {@link exportRuns}, which refuses one. */
563
+ searchRuns(params?: SearchRunsParams): Promise<{
564
+ runs: RunSummary[];
565
+ total: number;
566
+ }>;
567
+ /** Lists what the server holds for this key in a period, failures
568
+ * included, up to 10,000 rows. `truncated` is true when the period
569
+ * holds more. The list states what was stored, not a verdict, and a
570
+ * call that never reached Verdifax cannot appear in it. */
571
+ exportRuns(params?: ExportRunsParams): Promise<RunsExport>;
572
+ /** The same rows as {@link exportRuns}: the raw CSV text with `total`
573
+ * and `truncated` from the response headers. Check `truncated`: when
574
+ * true, the CSV is missing rows for the period. Throws when the server
575
+ * does not send those headers, so that a cut-off export cannot pass
576
+ * for a complete one. */
577
+ exportRunsCSV(params?: ExportRunsParams): Promise<RunsExportCSV>;
578
+ private exportPath;
579
+ listAttestations(params?: ListAttestationsParams): Promise<AttestationList>;
580
+ getAttestation(attestationId: number): Promise<Record<string, unknown>>;
289
581
  getAllowToken(runId: number): Promise<Record<string, unknown>>;
290
582
  getDenyReceipt(runId: number): Promise<Record<string, unknown>>;
291
583
  getCCVHaltReceipt(runId: number): Promise<Record<string, unknown>>;
292
584
  getMACCHaltReceipt(runId: number): Promise<Record<string, unknown>>;
293
585
  getAivpT4HaltReceipt(runId: number): Promise<Record<string, unknown>>;
586
+ getAttestationGapReceipt(runId: number): Promise<Record<string, unknown>>;
587
+ getCESAuditRecord(runId: number): Promise<Record<string, unknown>>;
588
+ /** The audit report for a run, as JSON. */
589
+ getRunReport(runId: number): Promise<Record<string, unknown>>;
590
+ /** The run's sealed audit bundle as the exact JSON text the server
591
+ * sent, to save and check with `verdifax-verify`. It is not parsed:
592
+ * JSON.parse would round a number above 2^53 and the recomputed hash
593
+ * would stop matching. */
594
+ getRunArtifacts(runId: number): Promise<string>;
595
+ /** The public audit bundle of a record published by run id, as the
596
+ * exact JSON text the server sent. Needs no API key. */
597
+ getPublicBundle(runId: number): Promise<string>;
598
+ /** The public audit bundle a share token points to, as the exact JSON
599
+ * text the server sent. Needs no API key. */
600
+ getPublicBundleByToken(token: string): Promise<string>;
294
601
  private getRunArtifact;
295
602
  /** Streams the audit PDF bytes as a Buffer. Format defaults to
296
603
  * "comprehensive" when not specified. */
@@ -301,27 +608,37 @@ declare class VerdifaxClient {
301
608
  adminCreateKey(name: string): Promise<AdminCreateKeyResponse>;
302
609
  adminListKeys(): Promise<AdminAPIKey[]>;
303
610
  adminRevokeKey(keyId: number): Promise<void>;
304
- /** Convenience for attesting an Anthropic Claude API response.
305
- * Wires the response text into the AIVP governance pipeline
306
- * by setting `ai_output_text`. */
611
+ /** Convenience for attesting an Anthropic Claude API response. With
612
+ * `govern: true` the response text also goes to the AIVP review as
613
+ * `ai_output_text`; that is off by default, so the text leaves your
614
+ * machine for review only when you ask. */
307
615
  attestClaudeResponse(args: {
308
616
  program_id: Hex64;
309
617
  route_id: string;
310
618
  registry_record_hash: Hex64;
311
619
  prompt: string;
312
620
  response: string;
621
+ govern?: boolean;
313
622
  }): Promise<ExecuteResponse>;
314
- /** Convenience for attesting an OpenAI API response. */
623
+ /** Convenience for attesting an OpenAI API response. `govern` works as
624
+ * in {@link attestClaudeResponse}. */
315
625
  attestOpenAIResponse(args: {
316
626
  program_id: Hex64;
317
627
  route_id: string;
318
628
  registry_record_hash: Hex64;
319
629
  prompt: string;
320
630
  response: string;
631
+ govern?: boolean;
321
632
  }): Promise<ExecuteResponse>;
322
633
  private attestProviderResponse;
323
634
  private request;
635
+ /** A GET whose body is kept as sent, retried like any other GET. */
636
+ private requestRaw;
324
637
  private requireAPIKey;
638
+ private requireExecuteFields;
639
+ /** The request with its derived flags and, with a signing key, a fresh
640
+ * signature and nonce, on a copy. */
641
+ private prepared;
325
642
  }
326
643
 
327
644
  /**
@@ -330,7 +647,9 @@ declare class VerdifaxClient {
330
647
  *
331
648
  * Variables consumed (identical names across SDKs):
332
649
  *
333
- * VERDIFAX_BASE_URL base URL (defaults to https://api.verdifax.com)
650
+ * VERDIFAX_BASE_URL base URL, read first
651
+ * VERDIFAX_API_URL base URL, read when VERDIFAX_BASE_URL is unset
652
+ * (defaults to https://api.verdifax.com)
334
653
  * VERDIFAX_API_KEY X-Verdifax-Key value
335
654
  * VERDIFAX_TIMEOUT_MS per-request timeout in ms (defaults to 90000)
336
655
  * VERDIFAX_USER_AGENT override the default User-Agent
@@ -339,6 +658,121 @@ declare class VerdifaxClient {
339
658
 
340
659
  declare function fromEnv(): VerdifaxClient;
341
660
 
661
+ /**
662
+ * Best-effort detection of the running Node environment, for the
663
+ * `reproducibility_context` of a run. A value that cannot be read is
664
+ * left out, and the server records it as not declared.
665
+ */
666
+
667
+ interface CaptureEnvironmentOptions {
668
+ /** Library name to seed value. Recorded as declared; the caller still
669
+ * has to apply the seeds. */
670
+ declaredSeeds?: Record<string, string | number>;
671
+ /** List the packages under `node_modules` in the working directory.
672
+ * Defaults to true. */
673
+ includeDependencies?: boolean;
674
+ /** Read the commit with `git rev-parse HEAD`. Defaults to true. */
675
+ includeGit?: boolean;
676
+ /** Read the container id from `/proc/self/cgroup` on Linux. Defaults
677
+ * to true. */
678
+ includeContainer?: boolean;
679
+ }
680
+ /** Auto-detects the running Node environment. */
681
+ declare function captureEnvironment(options?: CaptureEnvironmentOptions): ReproducibilityContext;
682
+
683
+ /**
684
+ * Request-body rules shared by every path to POST /execute.
685
+ */
686
+
687
+ /**
688
+ * The payload the provider helpers attest: canonical JSON with sorted keys,
689
+ * no extra whitespace and UTF-8 text, exactly
690
+ * `{"prompt":...,"provider":...,"response":...}`. All four SDKs produce the
691
+ * same bytes, and a shared test vector holds them to it.
692
+ *
693
+ * Text with an unpaired surrogate has no UTF-8 form and is refused.
694
+ */
695
+ declare function formatProviderPayload(provider: string, prompt: string, response: string): string;
696
+
697
+ /**
698
+ * The three canonical hash formulas from the Verdifax orchestrator, so a
699
+ * caller can recompute a DSE dispatch hash, a DCAE closure hash or a CRES
700
+ * receipt hash without calling the server.
701
+ *
702
+ * These match the Python SDK's `verdifax.section0` and pass its test
703
+ * vectors. Every hash is SHA-256 as 64 lowercase hex characters, over
704
+ * UTF-8 text.
705
+ */
706
+
707
+ declare const DSE_FORMULA_VERSION = "dse.tcu.dispatch.v1";
708
+ declare const DCAE_PREIMAGE_VERSION = "verdifax.dcae.v1";
709
+ declare const CRES_PREIMAGE_VERSION = "verdifax.cres.v1";
710
+ declare const CRES_ENGINE_VERSION = "verdifax-cres/1.0.0";
711
+ /** The DSE formula joins its fields with a period. */
712
+ declare function dseDispatchHash(fields: {
713
+ envelope_id: string;
714
+ sequence_id: string;
715
+ program_id: Hex64;
716
+ registry_record_hash: Hex64;
717
+ }): Hex64;
718
+ /** The DCAE formula joins its fields with a pipe. */
719
+ declare function dcaeClosureHash(fields: {
720
+ manifest_hash: Hex64;
721
+ aer_hash: Hex64;
722
+ envelope_id: string;
723
+ zksp_binding_hash: Hex64;
724
+ formal_verifier_status: string;
725
+ }): Hex64;
726
+ /** The CRES formula joins its fields with a pipe. `engine_version`
727
+ * defaults to {@link CRES_ENGINE_VERSION}; pass another value only to
728
+ * recompute a receipt from an earlier engine. */
729
+ declare function cresReceiptHash(fields: {
730
+ envelope_id: string;
731
+ field_path: string;
732
+ deletion_clock: string;
733
+ actor_id: string;
734
+ ciphertext_hash_at_shred: Hex64;
735
+ dsar_reference: string;
736
+ engine_version?: string;
737
+ }): Hex64;
738
+
739
+ /**
740
+ * Optional customer request signing.
741
+ *
742
+ * A customer can register an Ed25519 public key on an API key. From then
743
+ * on the orchestrator accepts a run only with a signature by the matching
744
+ * private key. The private key stays with the customer: it is never sent
745
+ * to the server, logged, or placed in an error message.
746
+ */
747
+
748
+ /** Creates a new Ed25519 key pair on this machine, as raw bytes: a
749
+ * 32-byte public key and a 32-byte private key. Nothing is sent to
750
+ * the server. Store the private key as a secret. */
751
+ declare function generateRequestKeyPair(): RequestKeyPair;
752
+ /** The bytes a request signature signs: the fields joined with single
753
+ * zero bytes, matching the orchestrator's RequestSignaturePreimage. */
754
+ declare function requestSignaturePreimage(fields: {
755
+ payload_hash: string;
756
+ program_id: string;
757
+ route_id: string;
758
+ registry_record_hash: string;
759
+ signed_at: string;
760
+ nonce: string;
761
+ }): Buffer;
762
+ /** Signs one execute request. The server hashes payload_text when it is
763
+ * non-empty, otherwise the payload string exactly as sent (it does not
764
+ * base64-decode it), so this does the same.
765
+ *
766
+ * `signedAt` and `nonce` default to the current time and fresh random
767
+ * bytes. A nonce the server has already seen is refused. */
768
+ declare function signRequest(signingKey: Uint8Array | KeyObject, req: ExecuteRequest, options?: {
769
+ signedAt?: string;
770
+ nonce?: string;
771
+ }): RequestSignature;
772
+ /** The body of POST /keys/request-key: the base64 public key and a
773
+ * signature proving the caller holds its private key. */
774
+ declare function requestKeyRegistrationBody(signingKey: Uint8Array | KeyObject): RequestKeyRegistrationBody;
775
+
342
776
  /**
343
777
  * Input-validation helpers, mirrors the Python SDK's
344
778
  * `_validation.py` and the Go SDK's `validation.go` for
@@ -411,4 +845,4 @@ declare class APIKeyRequiredError extends VerdifaxError {
411
845
  constructor();
412
846
  }
413
847
 
414
- export { APIError, APIKeyRequiredError, type AdminAPIKey, type AdminCreateKeyResponse, type AdminEraseRequest, type AttestRequest, AuthError, type ClientConfig, type DCAEProofBundle, type DCAEVerdict, type DeletionReceipt, type ExecuteRequest, type ExecuteResponse, type ExecutionManifest, type FormulaEra, type Health, type Hex64, type ListRunsParams, NotFoundError, type PDFFormat, type Run, type RunSummary, VerdifaxClient, VerdifaxError, type VerdifaxVersion, type VerifyResponse, fromEnv, validateHex64, validateRouteId };
848
+ export { APIError, APIKeyRequiredError, type AdminAPIKey, type AdminCreateKeyResponse, type AdminEraseRequest, type AttestRequest, type AttestationList, AuthError, CRES_ENGINE_VERSION, CRES_PREIMAGE_VERSION, type ClientConfig, type DCAEProofBundle, type DCAEVerdict, DCAE_PREIMAGE_VERSION, DSE_FORMULA_VERSION, type DeletionReceipt, type DeterminismDiff, type DeterminismRun, type ExecuteBatchResponse, type ExecuteBatchResult, type ExecuteRequest, type ExecuteResponse, type ExecutionManifest, type ExportRow, type ExportRunsParams, type FormulaEra, type Health, type Hex64, type ListAttestationsParams, type ListRunsParams, MAX_BATCH_ROWS, NotFoundError, type PDFFormat, RUN_STATUSES, type ReproducibilityContext, type RequestKeyPair, type RequestKeyRegistration, type RequestKeyRegistrationBody, type RequestSignature, type Run, type RunStats, type RunStatus, type RunSummary, type RunsExport, type RunsExportCSV, type SearchRunsParams, VerdifaxClient, VerdifaxError, type VerdifaxVersion, type VerifyDeterminismResponse, type VerifyResponse, captureEnvironment, cresReceiptHash, dcaeClosureHash, dseDispatchHash, formatProviderPayload, fromEnv, generateRequestKeyPair, requestKeyRegistrationBody, requestSignaturePreimage, signRequest, validateHex64, validateRouteId };