verdifax 0.3.0 → 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.js CHANGED
@@ -23,9 +23,20 @@ __export(index_exports, {
23
23
  APIError: () => APIError,
24
24
  APIKeyRequiredError: () => APIKeyRequiredError,
25
25
  AuthError: () => AuthError,
26
+ CRES_ENGINE_VERSION: () => CRES_ENGINE_VERSION,
27
+ CRES_PREIMAGE_VERSION: () => CRES_PREIMAGE_VERSION,
28
+ DCAE_PREIMAGE_VERSION: () => DCAE_PREIMAGE_VERSION,
29
+ DSE_FORMULA_VERSION: () => DSE_FORMULA_VERSION,
30
+ MAX_BATCH_ROWS: () => MAX_BATCH_ROWS,
26
31
  NotFoundError: () => NotFoundError,
32
+ RUN_STATUSES: () => RUN_STATUSES,
27
33
  VerdifaxClient: () => VerdifaxClient,
28
34
  VerdifaxError: () => VerdifaxError,
35
+ captureEnvironment: () => captureEnvironment,
36
+ cresReceiptHash: () => cresReceiptHash,
37
+ dcaeClosureHash: () => dcaeClosureHash,
38
+ dseDispatchHash: () => dseDispatchHash,
39
+ formatProviderPayload: () => formatProviderPayload,
29
40
  fromEnv: () => fromEnv,
30
41
  generateRequestKeyPair: () => generateRequestKeyPair,
31
42
  requestKeyRegistrationBody: () => requestKeyRegistrationBody,
@@ -157,6 +168,49 @@ function requestKeyRegistrationBody(signingKey) {
157
168
  return { public_key, proof };
158
169
  }
159
170
 
171
+ // src/helpers.ts
172
+ function formatProviderPayload(provider, prompt, response) {
173
+ if ([provider, prompt, response].some((text) => /[\uD800-\uDFFF]/u.test(text))) {
174
+ throw new VerdifaxError(
175
+ "verdifax: provider payload text cannot be encoded as UTF-8"
176
+ );
177
+ }
178
+ return JSON.stringify({ prompt, provider, response });
179
+ }
180
+ function isProvided(value) {
181
+ return value !== null && value !== void 0 && value !== "" && value !== false;
182
+ }
183
+ function withAttestedFlag(context) {
184
+ const provided = Object.entries(context).some(
185
+ ([name, value]) => name !== "attested" && isProvided(value)
186
+ );
187
+ return { ...context, attested: provided };
188
+ }
189
+ function withDeclaredFlag(context) {
190
+ const declared = Object.entries(context).some(
191
+ ([name, value]) => name !== "declared" && isProvided(value) && !(Array.isArray(value) && value.length === 0)
192
+ );
193
+ return { ...context, declared };
194
+ }
195
+ function refuseCallerOriginHashes(substance) {
196
+ const origin = substance?.origin;
197
+ if (origin?.source_ip_hash || origin?.user_agent_hash) {
198
+ throw new VerdifaxError(
199
+ "verdifax: request_substance.origin.source_ip_hash and user_agent_hash are computed by the server and cannot be supplied"
200
+ );
201
+ }
202
+ }
203
+ function withExecuteFlags(req) {
204
+ const body = { ...req };
205
+ if (req.attested_context) {
206
+ body.attested_context = withAttestedFlag(req.attested_context);
207
+ }
208
+ if (req.reproducibility_context) {
209
+ body.reproducibility_context = withDeclaredFlag(req.reproducibility_context);
210
+ }
211
+ return body;
212
+ }
213
+
160
214
  // src/validation.ts
161
215
  function validateHex64(value, fieldName) {
162
216
  if (typeof value !== "string" || value.length !== 64) {
@@ -187,7 +241,7 @@ function validateRouteId(value) {
187
241
  }
188
242
 
189
243
  // src/version.ts
190
- var SDK_VERSION = "0.3.0";
244
+ var SDK_VERSION = "1.0.0";
191
245
 
192
246
  // src/client.ts
193
247
  var DEFAULT_BASE_URL = "https://api.verdifax.com";
@@ -197,7 +251,10 @@ var DEFAULT_RETRY_BASE_DELAY_MS = 200;
197
251
  var SDK_USER_AGENT = `verdifax-sdk-node/${SDK_VERSION}`;
198
252
  var HEADER_API_KEY = "X-Verdifax-Key";
199
253
  var REQUEST_KEY_PATH = "/keys/request-key";
254
+ var HEADER_EXPORT_TOTAL = "X-Verdifax-Total";
255
+ var HEADER_EXPORT_TRUNCATED = "X-Verdifax-Truncated";
200
256
  var RETRYABLE_STATUSES = /* @__PURE__ */ new Set([429, 502, 503, 504]);
257
+ var MAX_BATCH_ROWS = 1e3;
201
258
  var VerdifaxClient = class {
202
259
  baseURL;
203
260
  apiKey;
@@ -222,21 +279,52 @@ var VerdifaxClient = class {
222
279
  async version() {
223
280
  return this.request("GET", "/version");
224
281
  }
282
+ /** The server's own API description. */
283
+ async getOpenAPI() {
284
+ return this.request("GET", "/openapi.json");
285
+ }
286
+ /** Run counts for this API key. */
287
+ async getStats() {
288
+ this.requireAPIKey();
289
+ return this.request("GET", "/stats");
290
+ }
225
291
  // ── Execute / Attest (auth) ───────────────────────────────────
226
292
  async execute(req) {
293
+ this.requireExecuteFields(req);
294
+ return this.request("POST", "/execute", this.prepared(req));
295
+ }
296
+ /** Runs one payload twice on the server and compares the manifest
297
+ * hashes. One signature covers the request, and the server claims
298
+ * its nonce once. Both runs are recorded. */
299
+ async verifyDeterminism(req) {
300
+ this.requireExecuteFields(req);
301
+ return this.request(
302
+ "POST",
303
+ "/execute/verify-determinism",
304
+ this.prepared(req)
305
+ );
306
+ }
307
+ /** Sends up to {@link MAX_BATCH_ROWS} runs in one request. With a
308
+ * signing key each row carries its own signature and nonce. A row
309
+ * that fails comes back in `results` with `ok: false`, so the call
310
+ * does not throw for it. The rows are not checked here: the server
311
+ * reports a bad row in that row's result.
312
+ *
313
+ * This is one POST and it is never retried. After a timeout the
314
+ * server may have run some or all of the rows. */
315
+ async executeBatch(runs) {
227
316
  this.requireAPIKey();
228
- if (!req.payload && !req.payload_text) {
229
- throw new VerdifaxError(
230
- "verdifax: ExecuteRequest needs payload or payload_text"
231
- );
317
+ if (!Array.isArray(runs) || runs.length === 0) {
318
+ throw new VerdifaxError("verdifax: executeBatch needs at least one run");
232
319
  }
233
- if (!req.program_id || !req.route_id || !req.registry_record_hash) {
320
+ if (runs.length > MAX_BATCH_ROWS) {
234
321
  throw new VerdifaxError(
235
- "verdifax: program_id, route_id, and registry_record_hash are required"
322
+ `verdifax: executeBatch accepts at most ${MAX_BATCH_ROWS} runs (got ${runs.length})`
236
323
  );
237
324
  }
238
- const body = this.signingKey ? { ...req, request_signature: signRequest(this.signingKey, req) } : req;
239
- return this.request("POST", "/execute", body);
325
+ return this.request("POST", "/execute/batch", {
326
+ runs: runs.map((run) => this.prepared(run))
327
+ });
240
328
  }
241
329
  /** High-level convenience wrapper around `execute()`. Accepts
242
330
  * either a Buffer (for binary payloads, auto-base64) or a
@@ -262,7 +350,12 @@ var VerdifaxClient = class {
262
350
  route_id: req.route_id,
263
351
  registry_record_hash: req.registry_record_hash,
264
352
  ai_output_text: req.ai_output_text,
265
- attested_context: req.attested_context
353
+ attested_context: req.attested_context,
354
+ reproducibility_context: req.reproducibility_context,
355
+ request_substance: req.request_substance,
356
+ authorization_chain: req.authorization_chain,
357
+ regulatory_scaffolding: req.regulatory_scaffolding,
358
+ causal_graph: req.causal_graph
266
359
  };
267
360
  if (req.payload !== void 0) {
268
361
  body.payload = Buffer.isBuffer(req.payload) ? req.payload.toString("base64") : Buffer.from(req.payload).toString("base64");
@@ -319,6 +412,94 @@ var VerdifaxClient = class {
319
412
  const out = await this.request("GET", path);
320
413
  return { runs: out.runs ?? [], total: out.total ?? 0 };
321
414
  }
415
+ /** Searches this key's runs. `manifest_hash` matches a prefix. The
416
+ * server ignores a `from` or `to` it cannot parse here, unlike
417
+ * {@link exportRuns}, which refuses one. */
418
+ async searchRuns(params = {}) {
419
+ this.requireAPIKey();
420
+ const q = new URLSearchParams();
421
+ for (const name of [
422
+ "manifest_hash",
423
+ "program_id",
424
+ "route_id",
425
+ "status",
426
+ "from",
427
+ "to"
428
+ ]) {
429
+ const value = params[name];
430
+ if (value) q.set(name, value);
431
+ }
432
+ if (params.limit && params.limit > 0) {
433
+ q.set("limit", String(params.limit));
434
+ }
435
+ if (params.offset && params.offset > 0) {
436
+ q.set("offset", String(params.offset));
437
+ }
438
+ const qs = q.toString();
439
+ const path = qs ? `/runs/search?${qs}` : "/runs/search";
440
+ const out = await this.request("GET", path);
441
+ return { runs: out.runs ?? [], total: out.total ?? 0 };
442
+ }
443
+ /** Lists what the server holds for this key in a period, failures
444
+ * included, up to 10,000 rows. `truncated` is true when the period
445
+ * holds more. The list states what was stored, not a verdict, and a
446
+ * call that never reached Verdifax cannot appear in it. */
447
+ async exportRuns(params = {}) {
448
+ this.requireAPIKey();
449
+ return this.request("GET", this.exportPath(params, "json"));
450
+ }
451
+ /** The same rows as {@link exportRuns}: the raw CSV text with `total`
452
+ * and `truncated` from the response headers. Check `truncated`: when
453
+ * true, the CSV is missing rows for the period. Throws when the server
454
+ * does not send those headers, so that a cut-off export cannot pass
455
+ * for a complete one. */
456
+ async exportRunsCSV(params = {}) {
457
+ this.requireAPIKey();
458
+ const { text, headers } = await this.requestRaw(
459
+ this.exportPath(params, "csv")
460
+ );
461
+ const total = Number.parseInt(headers.get(HEADER_EXPORT_TOTAL) ?? "", 10);
462
+ const truncated = headers.get(HEADER_EXPORT_TRUNCATED);
463
+ if (!Number.isSafeInteger(total) || truncated !== "true" && truncated !== "false") {
464
+ throw new VerdifaxError(
465
+ `verdifax: the server did not report ${HEADER_EXPORT_TOTAL} and ${HEADER_EXPORT_TRUNCATED}, so this CSV may be cut off; use exportRuns instead`
466
+ );
467
+ }
468
+ return { csv: text, total, truncated: truncated === "true" };
469
+ }
470
+ exportPath(params, format) {
471
+ const q = new URLSearchParams();
472
+ if (params.from) q.set("from", params.from);
473
+ if (params.to) q.set("to", params.to);
474
+ q.set("format", format);
475
+ return `/runs/export?${q.toString()}`;
476
+ }
477
+ // ── Attestation receipts (auth) ──────────────────────────────
478
+ async listAttestations(params = {}) {
479
+ this.requireAPIKey();
480
+ const q = new URLSearchParams();
481
+ if (params.limit && params.limit > 0) {
482
+ q.set("limit", String(params.limit));
483
+ }
484
+ if (params.offset && params.offset > 0) {
485
+ q.set("offset", String(params.offset));
486
+ }
487
+ const qs = q.toString();
488
+ return this.request(
489
+ "GET",
490
+ qs ? `/attestations?${qs}` : "/attestations"
491
+ );
492
+ }
493
+ async getAttestation(attestationId) {
494
+ this.requireAPIKey();
495
+ if (attestationId <= 0) {
496
+ throw new VerdifaxError("verdifax: attestationId must be > 0");
497
+ }
498
+ return this.request(
499
+ "GET",
500
+ `/attestations/${attestationId}`
501
+ );
502
+ }
322
503
  // ── Sealed-artifact retrieval (auth) ─────────────────────────
323
504
  async getAllowToken(runId) {
324
505
  return this.getRunArtifact(runId, "allow-token");
@@ -335,6 +516,39 @@ var VerdifaxClient = class {
335
516
  async getAivpT4HaltReceipt(runId) {
336
517
  return this.getRunArtifact(runId, "aivp-t4-halt-receipt");
337
518
  }
519
+ async getAttestationGapReceipt(runId) {
520
+ return this.getRunArtifact(runId, "attestation-gap-receipt");
521
+ }
522
+ async getCESAuditRecord(runId) {
523
+ return this.getRunArtifact(runId, "ces-audit-record");
524
+ }
525
+ /** The audit report for a run, as JSON. */
526
+ async getRunReport(runId) {
527
+ const out = await this.getRunArtifact(runId, "report");
528
+ return out.report;
529
+ }
530
+ /** The run's sealed audit bundle as the exact JSON text the server
531
+ * sent, to save and check with `verdifax-verify`. It is not parsed:
532
+ * JSON.parse would round a number above 2^53 and the recomputed hash
533
+ * would stop matching. */
534
+ async getRunArtifacts(runId) {
535
+ this.requireAPIKey();
536
+ if (runId <= 0) throw new VerdifaxError("verdifax: runId must be > 0");
537
+ return (await this.requestRaw(`/runs/${runId}/artifacts`)).text;
538
+ }
539
+ /** The public audit bundle of a record published by run id, as the
540
+ * exact JSON text the server sent. Needs no API key. */
541
+ async getPublicBundle(runId) {
542
+ if (runId <= 0) throw new VerdifaxError("verdifax: runId must be > 0");
543
+ return (await this.requestRaw(`/runs/${runId}/bundle.json`)).text;
544
+ }
545
+ /** The public audit bundle a share token points to, as the exact JSON
546
+ * text the server sent. Needs no API key. */
547
+ async getPublicBundleByToken(token) {
548
+ if (!token) throw new VerdifaxError("verdifax: token is required");
549
+ const path = `/public/runs/${encodeURIComponent(token)}/bundle.json`;
550
+ return (await this.requestRaw(path)).text;
551
+ }
338
552
  async getRunArtifact(runId, suffix) {
339
553
  this.requireAPIKey();
340
554
  if (runId <= 0) throw new VerdifaxError("verdifax: runId must be > 0");
@@ -421,13 +635,15 @@ var VerdifaxClient = class {
421
635
  await this.request("DELETE", `/admin/keys/${keyId}`);
422
636
  }
423
637
  // ── Provider helpers (Claude / OpenAI) ───────────────────────
424
- /** Convenience for attesting an Anthropic Claude API response.
425
- * Wires the response text into the AIVP governance pipeline
426
- * by setting `ai_output_text`. */
638
+ /** Convenience for attesting an Anthropic Claude API response. With
639
+ * `govern: true` the response text also goes to the AIVP review as
640
+ * `ai_output_text`; that is off by default, so the text leaves your
641
+ * machine for review only when you ask. */
427
642
  async attestClaudeResponse(args) {
428
643
  return this.attestProviderResponse({ ...args, provider: "anthropic" });
429
644
  }
430
- /** Convenience for attesting an OpenAI API response. */
645
+ /** Convenience for attesting an OpenAI API response. `govern` works as
646
+ * in {@link attestClaudeResponse}. */
431
647
  async attestOpenAIResponse(args) {
432
648
  return this.attestProviderResponse({ ...args, provider: "openai" });
433
649
  }
@@ -437,17 +653,16 @@ var VerdifaxClient = class {
437
653
  "verdifax: response is required for attestation"
438
654
  );
439
655
  }
440
- const payloadText = JSON.stringify({
441
- provider: args.provider,
442
- prompt: args.prompt,
443
- response: args.response
444
- });
445
656
  return this.attest({
446
- payload_text: payloadText,
657
+ payload_text: formatProviderPayload(
658
+ args.provider,
659
+ args.prompt,
660
+ args.response
661
+ ),
447
662
  program_id: args.program_id,
448
663
  route_id: args.route_id,
449
664
  registry_record_hash: args.registry_record_hash,
450
- ai_output_text: args.response,
665
+ ai_output_text: args.govern ? args.response : void 0,
451
666
  attested_context: {
452
667
  actor_role: "ai_assistant",
453
668
  model_provider: args.provider
@@ -455,7 +670,7 @@ var VerdifaxClient = class {
455
670
  });
456
671
  }
457
672
  // ── HTTP plumbing, retry-aware ──────────────────────────────
458
- async request(method, path, body) {
673
+ async request(method, path, body, rawText = false) {
459
674
  const url = this.baseURL + path;
460
675
  const headers = {
461
676
  "User-Agent": this.userAgent
@@ -512,6 +727,7 @@ var VerdifaxClient = class {
512
727
  throw new APIError(resp.status, path, errMessage);
513
728
  }
514
729
  }
730
+ if (rawText) return { text, headers: resp.headers };
515
731
  if (text.length === 0) return void 0;
516
732
  try {
517
733
  return JSON.parse(text);
@@ -525,17 +741,44 @@ var VerdifaxClient = class {
525
741
  `verdifax: retry budget exhausted${lastErr ? `: ${String(lastErr)}` : ""}`
526
742
  );
527
743
  }
744
+ /** A GET whose body is kept as sent, retried like any other GET. */
745
+ requestRaw(path) {
746
+ return this.request("GET", path, void 0, true);
747
+ }
528
748
  requireAPIKey() {
529
749
  if (!this.apiKey) throw new APIKeyRequiredError();
530
750
  }
751
+ requireExecuteFields(req) {
752
+ this.requireAPIKey();
753
+ if (!req.payload && !req.payload_text) {
754
+ throw new VerdifaxError(
755
+ "verdifax: ExecuteRequest needs payload or payload_text"
756
+ );
757
+ }
758
+ if (!req.program_id || !req.route_id || !req.registry_record_hash) {
759
+ throw new VerdifaxError(
760
+ "verdifax: program_id, route_id, and registry_record_hash are required"
761
+ );
762
+ }
763
+ validateHex64(req.program_id, "program_id");
764
+ validateHex64(req.registry_record_hash, "registry_record_hash");
765
+ validateRouteId(req.route_id);
766
+ refuseCallerOriginHashes(req.request_substance);
767
+ }
768
+ /** The request with its derived flags and, with a signing key, a fresh
769
+ * signature and nonce, on a copy. */
770
+ prepared(req) {
771
+ const body = withExecuteFlags(req);
772
+ return this.signingKey ? { ...body, request_signature: signRequest(this.signingKey, body) } : body;
773
+ }
531
774
  };
532
775
 
533
776
  // src/config.ts
534
777
  function fromEnv() {
535
778
  const cfg = {
536
- baseURL: process.env.VERDIFAX_BASE_URL ?? void 0,
779
+ baseURL: process.env.VERDIFAX_BASE_URL || process.env.VERDIFAX_API_URL || void 0,
537
780
  apiKey: process.env.VERDIFAX_API_KEY ?? void 0,
538
- userAgent: process.env.VERDIFAX_USER_AGENT ?? void 0
781
+ userAgent: process.env.VERDIFAX_USER_AGENT || void 0
539
782
  };
540
783
  const timeoutRaw = process.env.VERDIFAX_TIMEOUT_MS;
541
784
  if (timeoutRaw !== void 0 && timeoutRaw !== "") {
@@ -559,14 +802,177 @@ function fromEnv() {
559
802
  }
560
803
  return new VerdifaxClient(cfg);
561
804
  }
805
+
806
+ // src/environment.ts
807
+ var import_node_child_process = require("child_process");
808
+ var import_node_fs = require("fs");
809
+ var import_node_path = require("path");
810
+ var HASH_64 = /^[0-9a-f]{64}$/;
811
+ var GIT_SHA = /^([0-9a-f]{40}|[0-9a-f]{64})$/;
812
+ var PLATFORM_NAMES = { win32: "windows" };
813
+ var ARCH_NAMES = { x64: "amd64", ia32: "386" };
814
+ function packageVersion(dir) {
815
+ try {
816
+ const pkg = JSON.parse((0, import_node_fs.readFileSync)((0, import_node_path.join)(dir, "package.json"), "utf8"));
817
+ return pkg.name && pkg.version ? `${pkg.name}==${pkg.version}` : void 0;
818
+ } catch {
819
+ return void 0;
820
+ }
821
+ }
822
+ function packageDirs(root) {
823
+ const dirs = [];
824
+ for (const entry of (0, import_node_fs.readdirSync)(root)) {
825
+ if (entry.startsWith(".")) continue;
826
+ if (!entry.startsWith("@")) {
827
+ dirs.push((0, import_node_path.join)(root, entry));
828
+ continue;
829
+ }
830
+ for (const scoped of (0, import_node_fs.readdirSync)((0, import_node_path.join)(root, entry))) {
831
+ dirs.push((0, import_node_path.join)(root, entry, scoped));
832
+ }
833
+ }
834
+ return dirs;
835
+ }
836
+ function detectDependencies() {
837
+ try {
838
+ const pins = packageDirs((0, import_node_path.join)(process.cwd(), "node_modules")).map(packageVersion).filter((pin) => pin !== void 0);
839
+ pins.sort((a, b) => a.toLowerCase().localeCompare(b.toLowerCase()));
840
+ return pins.length > 0 ? pins : void 0;
841
+ } catch {
842
+ return void 0;
843
+ }
844
+ }
845
+ function detectGitSHA() {
846
+ try {
847
+ const sha = (0, import_node_child_process.execFileSync)("git", ["rev-parse", "HEAD"], {
848
+ encoding: "utf8",
849
+ stdio: ["ignore", "pipe", "ignore"],
850
+ timeout: 2e3
851
+ }).trim().toLowerCase();
852
+ return GIT_SHA.test(sha) ? sha : void 0;
853
+ } catch {
854
+ return void 0;
855
+ }
856
+ }
857
+ function detectContainerHash() {
858
+ try {
859
+ const text = (0, import_node_fs.readFileSync)("/proc/self/cgroup", "utf8");
860
+ return text.split("\n").flatMap((line) => line.split("/")).map((segment) => segment.trim()).find((segment) => HASH_64.test(segment));
861
+ } catch {
862
+ return void 0;
863
+ }
864
+ }
865
+ function captureEnvironment(options = {}) {
866
+ const seeds = Object.entries(options.declaredSeeds ?? {}).map(([name, seed]) => `${name}=${seed}`).sort();
867
+ const pinned = options.includeDependencies === false ? void 0 : detectDependencies();
868
+ const git = options.includeGit === false ? void 0 : detectGitSHA();
869
+ const container = options.includeContainer === false ? void 0 : detectContainerHash();
870
+ const os = PLATFORM_NAMES[process.platform] ?? process.platform;
871
+ const arch = ARCH_NAMES[process.arch] ?? process.arch;
872
+ return {
873
+ declared: true,
874
+ runtime_name: "node",
875
+ runtime_version: process.versions.node,
876
+ platform: `${os}/${arch}`,
877
+ ...pinned ? { pinned_dependencies: pinned } : {},
878
+ ...git ? { git_commit_sha: git } : {},
879
+ ...container ? { container_image_hash: container } : {},
880
+ ...seeds.length > 0 ? { random_seeds: seeds } : {}
881
+ };
882
+ }
883
+
884
+ // src/types.ts
885
+ var RUN_STATUSES = [
886
+ "ok",
887
+ "probe",
888
+ "pepg_deny",
889
+ "ccv_halt",
890
+ "macc_halt",
891
+ "aivp_t4_halt",
892
+ "attestation_gap",
893
+ "stage_error"
894
+ ];
895
+
896
+ // src/section0.ts
897
+ var import_node_crypto2 = require("crypto");
898
+ var DSE_FORMULA_VERSION = "dse.tcu.dispatch.v1";
899
+ var DCAE_PREIMAGE_VERSION = "verdifax.dcae.v1";
900
+ var CRES_PREIMAGE_VERSION = "verdifax.cres.v1";
901
+ var CRES_ENGINE_VERSION = "verdifax-cres/1.0.0";
902
+ function sha256Hex(preimage) {
903
+ return (0, import_node_crypto2.createHash)("sha256").update(Buffer.from(preimage, "utf8")).digest("hex");
904
+ }
905
+ function requireHex64(value, name) {
906
+ try {
907
+ validateHex64(value, name);
908
+ } catch (err) {
909
+ throw new VerdifaxError(
910
+ `verdifax: section0: ${err instanceof Error ? err.message : String(err)}`
911
+ );
912
+ }
913
+ }
914
+ function dseDispatchHash(fields) {
915
+ requireHex64(fields.program_id, "program_id");
916
+ requireHex64(fields.registry_record_hash, "registry_record_hash");
917
+ return sha256Hex(
918
+ [
919
+ DSE_FORMULA_VERSION,
920
+ fields.envelope_id,
921
+ fields.sequence_id,
922
+ fields.program_id,
923
+ fields.registry_record_hash
924
+ ].join(".")
925
+ );
926
+ }
927
+ function dcaeClosureHash(fields) {
928
+ requireHex64(fields.manifest_hash, "manifest_hash");
929
+ requireHex64(fields.aer_hash, "aer_hash");
930
+ requireHex64(fields.zksp_binding_hash, "zksp_binding_hash");
931
+ return sha256Hex(
932
+ [
933
+ DCAE_PREIMAGE_VERSION,
934
+ fields.manifest_hash,
935
+ fields.aer_hash,
936
+ fields.envelope_id,
937
+ fields.zksp_binding_hash,
938
+ fields.formal_verifier_status
939
+ ].join("|")
940
+ );
941
+ }
942
+ function cresReceiptHash(fields) {
943
+ requireHex64(fields.ciphertext_hash_at_shred, "ciphertext_hash_at_shred");
944
+ return sha256Hex(
945
+ [
946
+ CRES_PREIMAGE_VERSION,
947
+ fields.envelope_id,
948
+ fields.field_path,
949
+ fields.deletion_clock,
950
+ fields.actor_id,
951
+ fields.ciphertext_hash_at_shred,
952
+ fields.dsar_reference,
953
+ fields.engine_version ?? CRES_ENGINE_VERSION
954
+ ].join("|")
955
+ );
956
+ }
562
957
  // Annotate the CommonJS export names for ESM import in node:
563
958
  0 && (module.exports = {
564
959
  APIError,
565
960
  APIKeyRequiredError,
566
961
  AuthError,
962
+ CRES_ENGINE_VERSION,
963
+ CRES_PREIMAGE_VERSION,
964
+ DCAE_PREIMAGE_VERSION,
965
+ DSE_FORMULA_VERSION,
966
+ MAX_BATCH_ROWS,
567
967
  NotFoundError,
968
+ RUN_STATUSES,
568
969
  VerdifaxClient,
569
970
  VerdifaxError,
971
+ captureEnvironment,
972
+ cresReceiptHash,
973
+ dcaeClosureHash,
974
+ dseDispatchHash,
975
+ formatProviderPayload,
570
976
  fromEnv,
571
977
  generateRequestKeyPair,
572
978
  requestKeyRegistrationBody,