verdifax 1.0.0 → 1.2.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
@@ -68,9 +68,134 @@ interface ExecuteRequest {
68
68
  /** Caller-supplied record of what led to this run. Recorded as
69
69
  * supplied. */
70
70
  causal_graph?: Record<string, unknown>;
71
- /** Filled in by the client when the `signingKey` option is set. */
71
+ /** Places this run in a job map. Not accepted by a determinism check,
72
+ * which runs twice. */
73
+ job?: JobLink;
74
+ /** What this request declares for the rules of an active customer policy
75
+ * to read. Unknown keys and values outside the lists are refused before
76
+ * sending. */
77
+ policy_context?: PolicyContext;
78
+ /** The policy hash this request expects to run under. When another policy
79
+ * is active the server refuses the run with HTTP 409. */
80
+ expected_policy_hash?: Hex64;
81
+ /** A version 1 signature for an unsigned client to send. A client with
82
+ * the `signingKey` option sends version 2 and drops this field. */
72
83
  request_signature?: RequestSignature;
73
84
  }
85
+ /** Who the attested actor is, for a policy rule to read. */
86
+ type PolicyActorType = "agent" | "user" | "service" | "system";
87
+ /** What the request acts on, for a policy rule to read. */
88
+ type PolicyObjectType = "text" | "transaction" | "code" | "data" | "model" | "file";
89
+ /** A classification level, for a policy rule to read. */
90
+ type PolicyClassification = "PUBLIC" | "INTERNAL" | "CONFIDENTIAL" | "RESTRICTED" | "TOP_SECRET" | "TS_SCI";
91
+ /** The facts a request declares for the rules of a customer policy. These
92
+ * are the caller's own statements: a rule on them judges what was
93
+ * declared, and cannot show that it is true. Every key is optional, and
94
+ * the client refuses any other key before sending, because a misspelt key
95
+ * would be dropped and a rule on it would read its zero value.
96
+ *
97
+ * `actor_type`, `mfa_satisfied` and `session_age_seconds` describe the
98
+ * attested actor, so a request that sets one of them must also carry an
99
+ * `attested_context` naming the actor, for example its `actor_id`. */
100
+ interface PolicyContext {
101
+ actor_type?: PolicyActorType;
102
+ mfa_satisfied?: boolean;
103
+ /** A non-negative whole number of seconds. */
104
+ session_age_seconds?: number;
105
+ object_type?: PolicyObjectType;
106
+ /** At most 256 bytes of UTF-8. */
107
+ object_id?: string;
108
+ classification?: PolicyClassification;
109
+ }
110
+ /** A stored policy document, as POST /policies and GET /policies return
111
+ * it. */
112
+ interface Policy {
113
+ policy_id: string;
114
+ policy_version: string;
115
+ policy_hash: Hex64;
116
+ /** SHA-256 of the exact text that was uploaded. */
117
+ document_hash: Hex64;
118
+ created_at: string;
119
+ }
120
+ /** Returned by {@link VerdifaxClient.getPolicy}: the stored policy and its
121
+ * exact text. */
122
+ interface PolicyWithDocument extends Policy {
123
+ document: string;
124
+ }
125
+ /** Returned by {@link VerdifaxClient.listPolicies}. */
126
+ interface PolicyList {
127
+ ok: boolean;
128
+ /** The chain of this key's policy changes, for example `api-key-7`. */
129
+ chain_id?: string;
130
+ /** The newest change, or 64 zeros when there is none yet. */
131
+ newest_activation_hash: Hex64;
132
+ /** The document in force, or empty under the built-in policy. */
133
+ active_document_hash: string;
134
+ policies: Policy[];
135
+ }
136
+ /** The argument of {@link VerdifaxClient.testPolicy}: sample inputs and
137
+ * exactly one of `document` or `documentHash`. */
138
+ interface PolicyTestRequest {
139
+ /** Sample inputs for the rules, passed through as given. */
140
+ inputs: Record<string, unknown>;
141
+ /** The exact text of a policy to test. */
142
+ document?: string;
143
+ /** The document hash of a policy already uploaded under this key. */
144
+ documentHash?: Hex64;
145
+ }
146
+ /** Returned by {@link VerdifaxClient.testPolicy}. A test seals nothing. */
147
+ interface PolicyTestResult {
148
+ ok: boolean;
149
+ /** Always false. */
150
+ sealed: boolean;
151
+ outcome: string;
152
+ fired_rule_id: string;
153
+ reason_code: string;
154
+ }
155
+ /** The signature of a policy activation: the request key's approval of
156
+ * the change. */
157
+ interface PolicyActivationSignature {
158
+ /** Base64 Ed25519 signature by the request key. */
159
+ signature: string;
160
+ /** RFC 3339 UTC with whole seconds. */
161
+ signed_at: string;
162
+ /** 16 random bytes as 32 lowercase hex characters, fresh per change. */
163
+ nonce: string;
164
+ }
165
+ /** One policy change, as {@link VerdifaxClient.activatePolicy} and
166
+ * {@link VerdifaxClient.getPolicyHistory} return it. */
167
+ interface PolicyActivation {
168
+ format: string;
169
+ chain_id: string;
170
+ sequence: number;
171
+ previous_activation_hash: Hex64;
172
+ policy_id: string;
173
+ policy_version: string;
174
+ policy_hash: Hex64;
175
+ document_hash: Hex64;
176
+ activated_at: string;
177
+ /** Present when the request key signed the change. */
178
+ signature?: PolicyActivationSignature & {
179
+ public_key: string;
180
+ };
181
+ activation_hash: Hex64;
182
+ /** Where the change was logged on the public log. */
183
+ anchor?: Record<string, unknown>;
184
+ }
185
+ /** Places one run in a job. `job_id` and `step_id` are 1 to 128 letters,
186
+ * digits, dots, underscores, colons or dashes. The client sorts both
187
+ * lists, removes repeats and leaves out an empty list and a false
188
+ * `final`. */
189
+ interface JobLink {
190
+ job_id: string;
191
+ step_id: string;
192
+ /** Record hashes of the steps this one directly follows, in this job. */
193
+ previous_record_hashes?: Hex64[];
194
+ /** Record hashes from another account that this step follows. */
195
+ external_previous?: Hex64[];
196
+ /** True on the step that closes the job. */
197
+ final?: boolean;
198
+ }
74
199
  /** The runtime a caller declares for a run. Every field is optional.
75
200
  * The server records these values as given and does not check them. */
76
201
  interface ReproducibilityContext {
@@ -98,6 +223,27 @@ interface RequestSignature {
98
223
  /** 16 random bytes as 32 lowercase hex characters, fresh per request. */
99
224
  nonce: string;
100
225
  }
226
+ /** A version 2 request signature, which covers the exact `signed_request`
227
+ * text. */
228
+ interface RequestSignatureV2 extends RequestSignature {
229
+ version: "2";
230
+ }
231
+ /** The whole body of a signed call, and of each row of a signed batch.
232
+ * The server reads the request from `signed_request` alone. */
233
+ interface SignedRequestBody {
234
+ /** The request as JSON text, exactly as it was signed. */
235
+ signed_request: string;
236
+ request_signature: RequestSignatureV2;
237
+ }
238
+ /** The current key's approval of replacing or clearing itself. */
239
+ interface RequestKeyChange {
240
+ /** Base64 Ed25519 signature by the current key. */
241
+ signature: string;
242
+ /** RFC 3339 UTC with whole seconds. */
243
+ signed_at: string;
244
+ /** 16 random bytes as 32 lowercase hex characters, fresh per change. */
245
+ nonce: string;
246
+ }
101
247
  /** A key pair from {@link generateRequestKeyPair}, as raw bytes. */
102
248
  interface RequestKeyPair {
103
249
  /** The 32-byte Ed25519 public key. */
@@ -112,7 +258,8 @@ interface RequestKeyRegistrationBody {
112
258
  /** Base64 signature proving the caller holds the private key. */
113
259
  proof: string;
114
260
  }
115
- /** Returned by {@link VerdifaxClient.registerRequestKey}. */
261
+ /** Returned by {@link VerdifaxClient.registerRequestKey} and
262
+ * {@link VerdifaxClient.rotateRequestKey}. */
116
263
  interface RequestKeyRegistration {
117
264
  ok: boolean;
118
265
  public_key: string;
@@ -120,8 +267,16 @@ interface RequestKeyRegistration {
120
267
  interface ExecuteResponse {
121
268
  ok: boolean;
122
269
  run_id: number;
270
+ /** The record's hash: the manifest hash of a completed run. A refused or
271
+ * halted run throws an {@link APIError} carrying its `recordHash` and,
272
+ * when signed, its `signedRequest`. */
273
+ record_hash?: Hex64;
274
+ manifest_hash?: Hex64;
123
275
  manifest: ExecutionManifest;
124
276
  duration_ms: number;
277
+ /** The exact text that was signed, when the call was signed. Keep it to
278
+ * pass to `verdifax-verify --request FILE`. */
279
+ signed_request?: string;
125
280
  }
126
281
  /** One row of {@link ExecuteBatchResponse}. A successful row has
127
282
  * `manifest`. A failed row has `error`, and `error_stage` and a typed
@@ -131,11 +286,16 @@ interface ExecuteBatchResult {
131
286
  index: number;
132
287
  ok: boolean;
133
288
  run_id?: number;
289
+ /** The manifest hash of a completed row, or the receipt hash of a refused
290
+ * or halted one. */
291
+ record_hash?: Hex64;
134
292
  manifest_hash?: Hex64;
135
293
  manifest?: ExecutionManifest;
136
294
  error?: string;
137
295
  error_stage?: string;
138
296
  duration_ms: number;
297
+ /** The exact text that was signed for this row, when it was signed. */
298
+ signed_request?: string;
139
299
  partial_manifest?: ExecutionManifest;
140
300
  deny_receipt?: Record<string, unknown>;
141
301
  ccv_halt_receipt?: Record<string, unknown>;
@@ -176,6 +336,8 @@ interface VerifyDeterminismResponse {
176
336
  first: DeterminismRun;
177
337
  second: DeterminismRun;
178
338
  diff: DeterminismDiff;
339
+ /** The exact text that was signed, when the call was signed. */
340
+ signed_request?: string;
179
341
  }
180
342
  /**
181
343
  * Sealed manifest. Field names match the orchestrator's Go-default
@@ -284,6 +446,25 @@ interface AttestRequest {
284
446
  authorization_chain?: Record<string, unknown>;
285
447
  regulatory_scaffolding?: Record<string, unknown>;
286
448
  causal_graph?: Record<string, unknown>;
449
+ /** Places this run in a job map. {@link VerdifaxJob.step} fills it in. */
450
+ job?: JobLink;
451
+ /** What this request declares for the rules of a customer policy. */
452
+ policy_context?: PolicyContext;
453
+ /** The policy hash this request expects to run under. */
454
+ expected_policy_hash?: Hex64;
455
+ }
456
+ /** The second argument of {@link VerdifaxJob.step}: everything
457
+ * {@link VerdifaxClient.attest} takes except `job`, which the helper
458
+ * builds, plus the step's place in the job. */
459
+ interface JobStepOptions extends Omit<AttestRequest, "job"> {
460
+ /** Step ids in this job that this step directly follows. When omitted,
461
+ * the step follows the one run just before it through this helper. An
462
+ * empty list means it follows none. */
463
+ after?: string[];
464
+ /** Record hashes from another account that this step follows. */
465
+ external_previous?: Hex64[];
466
+ /** True on the step that closes the job. */
467
+ final?: boolean;
287
468
  }
288
469
  /** Optional filters for {@link VerdifaxClient.listRuns}. */
289
470
  interface ListRunsParams {
@@ -325,6 +506,8 @@ interface SearchRunsParams {
325
506
  interface ExportRunsParams {
326
507
  from?: string;
327
508
  to?: string;
509
+ /** Limits the export to the runs of one job. */
510
+ job_id?: string;
328
511
  }
329
512
  /** One run in an evidence export: what the server stored, not a verdict. */
330
513
  interface ExportRow {
@@ -338,6 +521,11 @@ interface ExportRow {
338
521
  leaf_hash: string;
339
522
  complete_record_entry_id: string;
340
523
  complete_record_leaf_hash: string;
524
+ /** Where the row's public-log entry was read from: `bundle`, `receipt`
525
+ * or `none`. */
526
+ anchor_source?: string;
527
+ job_id?: string;
528
+ step_id?: string;
341
529
  }
342
530
  /** Body returned by GET /runs/export in JSON form. */
343
531
  interface RunsExport {
@@ -453,6 +641,47 @@ interface AdminAPIKey {
453
641
  revoked: boolean;
454
642
  }
455
643
 
644
+ /**
645
+ * The job helper: runs the steps of one job and keeps the map of step ids
646
+ * to record hashes, so a later step can name the steps it follows.
647
+ */
648
+
649
+ /** Returned by {@link VerdifaxClient.job}.
650
+ *
651
+ * Every step goes through `attest`, so it signs when the client signs. A
652
+ * refused or halted step stays in the map and a later step can name it.
653
+ * A step that sealed nothing, for example a timeout or a 409, is not in the
654
+ * map and does not move the default `after`, so it can run again under the
655
+ * same id. An empty `after` starts another root step.
656
+ *
657
+ * `signedRequests` holds the payloads of signed steps, so it is a private
658
+ * field: logging a job prints the hashes and not that text.
659
+ *
660
+ * To run branches at the same time, give each its `after`: the default
661
+ * reads the last step that finished. */
662
+ declare class VerdifaxJob {
663
+ #private;
664
+ readonly jobId: string;
665
+ private readonly client;
666
+ private readonly hashes;
667
+ private lastStepId;
668
+ constructor(client: {
669
+ attest(req: AttestRequest): Promise<ExecuteResponse>;
670
+ }, jobId: string);
671
+ /** Step id to record hash for every step that left a record, on a copy. */
672
+ get recordHashes(): Record<string, Hex64>;
673
+ /** Step id to the exact text that was signed, for every signed step that
674
+ * left a record, refused and halted steps included, on a copy. Each text
675
+ * can be passed to `verdifax-verify --request FILE`. */
676
+ get signedRequests(): Record<string, string>;
677
+ /** Runs one step and records its hash and signed text. A refused or halted
678
+ * step records both from the error, then throws the same error `attest`
679
+ * throws. */
680
+ step(stepId: string, options: JobStepOptions): Promise<ExecuteResponse>;
681
+ private previousHashes;
682
+ private record;
683
+ }
684
+
456
685
  /** The most rows POST /execute/batch accepts in one request. */
457
686
  declare const MAX_BATCH_ROWS = 1000;
458
687
  /**
@@ -496,14 +725,25 @@ declare const MAX_BATCH_ROWS = 1000;
496
725
  * | `adminCreateKey(name)` | POST /admin/keys | required |
497
726
  * | `adminListKeys()` | GET /admin/keys | required |
498
727
  * | `adminRevokeKey(id)` | DELETE /admin/keys/{id} | required |
728
+ * | `adminClearRequestKey(id)` | DELETE /admin/keys/{id}/request-key | required |
499
729
  * | `attestClaudeResponse(...)` | POST /execute (helper) | required |
500
730
  * | `attestOpenAIResponse(...)` | POST /execute (helper) | required |
501
731
  * | `registerRequestKey()` | POST /keys/request-key | required |
732
+ * | `rotateRequestKey(newSigningKey)` | POST /keys/request-key | required |
502
733
  * | `clearRequestKey()` | DELETE /keys/request-key | required |
734
+ * | `uploadPolicy(document)` | POST /policies | required |
735
+ * | `listPolicies()` | GET /policies | required |
736
+ * | `getPolicy(documentHash)` | GET /policies/{document_hash} | required |
737
+ * | `testPolicy(req)` | POST /policies/test | required |
738
+ * | `getPolicyHistory()` | GET /policies/history | required |
739
+ * | `activatePolicy(documentHash)` | POST /policies/{document_hash}/activate | required |
740
+ * | `job(jobId)` | none, returns a {@link VerdifaxJob} | none |
503
741
  *
504
742
  * With the `signingKey` option set, every path to POST /execute carries
505
743
  * a fresh request signature, each row of a batch carries its own, and a
506
- * determinism check carries one. Without it, requests are unsigned.
744
+ * determinism check carries one. Each sends `signed_request` and
745
+ * `request_signature` and nothing else, and the result carries the signed
746
+ * text as `signed_request`. Without it, requests are unsigned.
507
747
  *
508
748
  * Idempotent GETs that hit a transient failure (502/503/504/429)
509
749
  * are retried with exponential backoff + full jitter. Non-
@@ -517,7 +757,7 @@ declare class VerdifaxClient {
517
757
  private readonly userAgent;
518
758
  private readonly maxRetries;
519
759
  private readonly retryBaseDelayMs;
520
- private readonly signingKey;
760
+ private signingKey;
521
761
  constructor(config?: ClientConfig);
522
762
  health(): Promise<Health>;
523
763
  version(): Promise<VerdifaxVersion>;
@@ -528,13 +768,16 @@ declare class VerdifaxClient {
528
768
  execute(req: ExecuteRequest): Promise<ExecuteResponse>;
529
769
  /** Runs one payload twice on the server and compares the manifest
530
770
  * hashes. One signature covers the request, and the server claims
531
- * its nonce once. Both runs are recorded. */
771
+ * its nonce once. Both runs are recorded. A run that happens twice
772
+ * cannot be one job step, so a `job` is refused here. */
532
773
  verifyDeterminism(req: ExecuteRequest): Promise<VerifyDeterminismResponse>;
533
774
  /** Sends up to {@link MAX_BATCH_ROWS} runs in one request. With a
534
775
  * signing key each row carries its own signature and nonce. A row
535
776
  * 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.
777
+ * does not throw for it. The rows are not checked here, except a job
778
+ * block, a `policy_context` and an `expected_policy_hash`, which are
779
+ * refused before anything is sent: the server reports any other bad row
780
+ * in that row's result.
538
781
  *
539
782
  * This is one POST and it is never retried. After a timeout the
540
783
  * server may have run some or all of the rows. */
@@ -544,13 +787,62 @@ declare class VerdifaxClient {
544
787
  * string (for plain text). Validates the hex fields and
545
788
  * routes the call through to the canonical /execute. */
546
789
  attest(req: AttestRequest): Promise<ExecuteResponse>;
790
+ /** A helper that runs the steps of one job through {@link attest} and
791
+ * keeps each step's record hash, so a later step can name it. It makes
792
+ * no request until a step runs. */
793
+ job(jobId: string): VerdifaxJob;
547
794
  /** Registers this client's public key on its API key, with the proof
548
795
  * that the client holds the private key. From then on the server
549
796
  * refuses a run on this API key without a request signature. */
550
797
  registerRequestKey(): Promise<RequestKeyRegistration>;
798
+ /** Replaces the registered key with `newSigningKey`. The new key proves
799
+ * itself and this client's current key approves the change. After
800
+ * success this client signs with the new key. If the call fails it
801
+ * keeps the current key, including after a timeout, when the server may
802
+ * have made the change. */
803
+ rotateRequestKey(newSigningKey: Uint8Array | KeyObject): Promise<RequestKeyRegistration>;
551
804
  /** Clears the registered public key, so the server stops requiring
552
- * request signatures on this API key. */
805
+ * request signatures on this API key. With a signing key the client
806
+ * sends that key's approval, which the server requires while a key is
807
+ * registered. After success the client drops its signing key and sends
808
+ * unsigned requests, because the server refuses a signed run on an API
809
+ * key with no registered key. If the call fails it keeps the key. */
553
810
  clearRequestKey(): Promise<void>;
811
+ /** Stores a policy document. Nothing changes until it is activated with
812
+ * {@link activatePolicy}. The server hashes the exact text, so this
813
+ * sends the string it is given unchanged and refuses anything that is
814
+ * not a string: serializing an object here would change the hash.
815
+ * Verdifax does not write, review or approve a customer's policy. */
816
+ uploadPolicy(document: string): Promise<Policy>;
817
+ /** This key's stored documents, with the chain its changes belong to,
818
+ * the newest change in it (64 zeros when there is none yet) and the
819
+ * document in force (empty under the built-in policy). */
820
+ listPolicies(): Promise<PolicyList>;
821
+ /** One stored document, with its exact text as `document`. */
822
+ getPolicy(documentHash: Hex64): Promise<PolicyWithDocument>;
823
+ /** Shows which rule would fire on sample inputs, for a document given as
824
+ * text or one already stored, named by its hash: exactly one of the two.
825
+ * It seals nothing. */
826
+ testPolicy(req: PolicyTestRequest): Promise<PolicyTestResult>;
827
+ /** This key's policy changes, oldest first, as the list the server sends.
828
+ * Save it as JSON, for example with
829
+ * `writeFileSync("policy-history.json", JSON.stringify(history))`, and
830
+ * check it with `verdifax-verify --policy-history policy-history.json`. */
831
+ getPolicyHistory(): Promise<PolicyActivation[]>;
832
+ /** Makes a stored document the policy in force and returns the change
833
+ * record. It first reads GET /policies for the chain and its newest
834
+ * change, then names that change as the one this follows. With the
835
+ * `signingKey` option the request key signs the change, which the server
836
+ * requires while a request key is registered.
837
+ *
838
+ * Rolling back is activating an earlier document: it is one more change
839
+ * in the chain, so the change it undoes stays on the record.
840
+ *
841
+ * An HTTP 409 means the chain moved because another change came first,
842
+ * or the document is not yet effective. It throws the usual
843
+ * {@link APIError} and is not retried: read the policies again and
844
+ * decide. */
845
+ activatePolicy(documentHash: Hex64): Promise<PolicyActivation>;
554
846
  getRun(runId: number): Promise<Run>;
555
847
  verifyRun(runId: number): Promise<VerifyResponse>;
556
848
  listRuns(params?: ListRunsParams): Promise<{
@@ -608,6 +900,10 @@ declare class VerdifaxClient {
608
900
  adminCreateKey(name: string): Promise<AdminCreateKeyResponse>;
609
901
  adminListKeys(): Promise<AdminAPIKey[]>;
610
902
  adminRevokeKey(keyId: number): Promise<void>;
903
+ /** Clears the request key on an API key whose holder lost it, after a
904
+ * manual check. It is the one way to clear a key without that key. The
905
+ * id can be any API key, so this client keeps its own signing key. */
906
+ adminClearRequestKey(keyId: number): Promise<void>;
611
907
  /** Convenience for attesting an Anthropic Claude API response. With
612
908
  * `govern: true` the response text also goes to the AIVP review as
613
909
  * `ai_output_text`; that is off by default, so the text leaves your
@@ -619,6 +915,9 @@ declare class VerdifaxClient {
619
915
  prompt: string;
620
916
  response: string;
621
917
  govern?: boolean;
918
+ job?: JobLink;
919
+ policy_context?: PolicyContext;
920
+ expected_policy_hash?: Hex64;
622
921
  }): Promise<ExecuteResponse>;
623
922
  /** Convenience for attesting an OpenAI API response. `govern` works as
624
923
  * in {@link attestClaudeResponse}. */
@@ -629,6 +928,9 @@ declare class VerdifaxClient {
629
928
  prompt: string;
630
929
  response: string;
631
930
  govern?: boolean;
931
+ job?: JobLink;
932
+ policy_context?: PolicyContext;
933
+ expected_policy_hash?: Hex64;
632
934
  }): Promise<ExecuteResponse>;
633
935
  private attestProviderResponse;
634
936
  private request;
@@ -636,8 +938,8 @@ declare class VerdifaxClient {
636
938
  private requestRaw;
637
939
  private requireAPIKey;
638
940
  private requireExecuteFields;
639
- /** The request with its derived flags and, with a signing key, a fresh
640
- * signature and nonce, on a copy. */
941
+ /** The body to send, on a copy: the request with its derived flags or,
942
+ * with a signing key, the signed text with a fresh signature and nonce. */
641
943
  private prepared;
642
944
  }
643
945
 
@@ -693,6 +995,9 @@ declare function captureEnvironment(options?: CaptureEnvironmentOptions): Reprod
693
995
  * Text with an unpaired surrogate has no UTF-8 form and is refused.
694
996
  */
695
997
  declare function formatProviderPayload(provider: string, prompt: string, response: string): string;
998
+ /** Every top-level key a run request may hold. Any other key is refused
999
+ * before sending, so a misspelt field cannot be silently dropped. */
1000
+ declare const EXECUTE_FIELDS: readonly string[];
696
1001
 
697
1002
  /**
698
1003
  * The three canonical hash formulas from the Verdifax orchestrator, so a
@@ -749,8 +1054,9 @@ declare function cresReceiptHash(fields: {
749
1054
  * 32-byte public key and a 32-byte private key. Nothing is sent to
750
1055
  * the server. Store the private key as a secret. */
751
1056
  declare function generateRequestKeyPair(): RequestKeyPair;
752
- /** The bytes a request signature signs: the fields joined with single
753
- * zero bytes, matching the orchestrator's RequestSignaturePreimage. */
1057
+ /** The bytes a version 1 request signature signs: the fields joined with
1058
+ * single zero bytes, matching the orchestrator's RequestSignaturePreimage.
1059
+ * The client now sends version 2. See {@link requestSignaturePreimageV2}. */
754
1060
  declare function requestSignaturePreimage(fields: {
755
1061
  payload_hash: string;
756
1062
  program_id: string;
@@ -759,9 +1065,37 @@ declare function requestSignaturePreimage(fields: {
759
1065
  signed_at: string;
760
1066
  nonce: string;
761
1067
  }): 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.
1068
+ /** The bytes a version 2 request signature signs: the fields joined with
1069
+ * single zero bytes, matching the orchestrator's
1070
+ * RequestSignaturePreimageV2. With no job, the job fields are empty and
1071
+ * `final` is false. */
1072
+ declare function requestSignaturePreimageV2(fields: {
1073
+ body_hash: string;
1074
+ payload_hash: string;
1075
+ program_id: string;
1076
+ route_id: string;
1077
+ registry_record_hash: string;
1078
+ ai_output_hash: string;
1079
+ job?: JobLink;
1080
+ signed_at: string;
1081
+ nonce: string;
1082
+ }): Buffer;
1083
+ /** Signs one execute request with signature version 2 and returns the
1084
+ * whole body to send. The request is serialized once, and that exact text
1085
+ * is what is hashed, signed and sent.
1086
+ *
1087
+ * The payload hash follows the same rule as {@link signRequest}.
1088
+ * `signedAt` and `nonce` default to the current time and fresh random
1089
+ * bytes. A nonce the server has already seen is refused. */
1090
+ declare function signRequestV2(signingKey: Uint8Array | KeyObject, req: ExecuteRequest, options?: {
1091
+ signedAt?: string;
1092
+ nonce?: string;
1093
+ }): SignedRequestBody;
1094
+ /** Signs one execute request with signature version 1, which the server
1095
+ * still accepts. The client now sends version 2: see {@link signRequestV2}.
1096
+ * The server hashes payload_text when it is non-empty, otherwise the
1097
+ * payload string exactly as sent (it does not base64-decode it), so this
1098
+ * does the same.
765
1099
  *
766
1100
  * `signedAt` and `nonce` default to the current time and fresh random
767
1101
  * bytes. A nonce the server has already seen is refused. */
@@ -772,6 +1106,44 @@ declare function signRequest(signingKey: Uint8Array | KeyObject, req: ExecuteReq
772
1106
  /** The body of POST /keys/request-key: the base64 public key and a
773
1107
  * signature proving the caller holds its private key. */
774
1108
  declare function requestKeyRegistrationBody(signingKey: Uint8Array | KeyObject): RequestKeyRegistrationBody;
1109
+ /** The bytes the current key signs to replace or clear itself. `new_public_key`
1110
+ * is the new base64 public key, or empty when clearing. */
1111
+ declare function requestKeyChangePreimage(fields: {
1112
+ new_public_key: string;
1113
+ signed_at: string;
1114
+ nonce: string;
1115
+ }): Buffer;
1116
+ /** The current key's approval of a key change, the `change` value of POST
1117
+ * and DELETE /keys/request-key. Pass an empty `newPublicKey` when clearing.
1118
+ * `signedAt` and `nonce` default to the current time and fresh random
1119
+ * bytes. */
1120
+ declare function requestKeyChangeApproval(currentSigningKey: Uint8Array | KeyObject, newPublicKey: string, options?: {
1121
+ signedAt?: string;
1122
+ nonce?: string;
1123
+ }): RequestKeyChange;
1124
+ /** The bytes the request key signs to make a stored policy document the
1125
+ * one in force, matching the orchestrator's PolicyActivationPreimage.
1126
+ * `chain_id` and `previous_activation_hash` come from GET /policies, so a
1127
+ * signature cannot be used on another key's chain, another document or
1128
+ * another point in the chain. */
1129
+ declare function policyActivationPreimage(fields: {
1130
+ chain_id: string;
1131
+ document_hash: string;
1132
+ previous_activation_hash: string;
1133
+ signed_at: string;
1134
+ nonce: string;
1135
+ }): Buffer;
1136
+ /** The request key's approval of a policy change, the `signature` value of
1137
+ * POST /policies/{document_hash}/activate. `signedAt` and `nonce` default
1138
+ * to the current time and fresh random bytes. */
1139
+ declare function policyActivationApproval(signingKey: Uint8Array | KeyObject, fields: {
1140
+ chain_id: string;
1141
+ document_hash: string;
1142
+ previous_activation_hash: string;
1143
+ }, options?: {
1144
+ signedAt?: string;
1145
+ nonce?: string;
1146
+ }): PolicyActivationSignature;
775
1147
 
776
1148
  /**
777
1149
  * Input-validation helpers, mirrors the Python SDK's
@@ -791,6 +1163,9 @@ declare function validateHex64(value: string, fieldName: string): void;
791
1163
  * a wider character set, but the SDK enforces the conservative
792
1164
  * subset by default to catch typos early. */
793
1165
  declare function validateRouteId(value: string): void;
1166
+ /** Throws unless `value` is a job or step name: 1 to 128 letters, digits,
1167
+ * dots, underscores, colons or dashes, the server's own rule. */
1168
+ declare function validateJobName(value: string, fieldName: string): void;
794
1169
 
795
1170
  /**
796
1171
  * Typed errors returned by the Verdifax SDK.
@@ -830,13 +1205,22 @@ declare class NotFoundError extends VerdifaxError {
830
1205
  constructor(path: string, message: string);
831
1206
  }
832
1207
  /** Every other non-2xx response. Carries the HTTP status and
833
- * the path so callers can switch on either dimension. */
1208
+ * the path so callers can switch on either dimension. `recordHash` is
1209
+ * the receipt hash of a refused or halted run, when the server sealed
1210
+ * one; it is undefined when no record exists.
1211
+ *
1212
+ * `signedRequest` is the exact text that was signed, when the call was a
1213
+ * signed run. Keep it to pass to `verdifax-verify --request FILE`. It holds
1214
+ * the payload, so it stays out of the message and is not enumerable: read
1215
+ * it by name, and logging the error does not print it. */
834
1216
  declare class APIError extends VerdifaxError {
835
1217
  readonly status: number;
836
1218
  readonly path: string;
837
1219
  readonly message: string;
1220
+ readonly recordHash?: string | undefined;
838
1221
  readonly name: string;
839
- constructor(status: number, path: string, message: string);
1222
+ readonly signedRequest?: string;
1223
+ constructor(status: number, path: string, message: string, recordHash?: string | undefined, signedRequest?: string);
840
1224
  }
841
1225
  /** Returned when an authenticated method is called on a client
842
1226
  * constructed without an apiKey. */
@@ -845,4 +1229,4 @@ declare class APIKeyRequiredError extends VerdifaxError {
845
1229
  constructor();
846
1230
  }
847
1231
 
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 };
1232
+ 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, EXECUTE_FIELDS, type ExecuteBatchResponse, type ExecuteBatchResult, type ExecuteRequest, type ExecuteResponse, type ExecutionManifest, type ExportRow, type ExportRunsParams, type FormulaEra, type Health, type Hex64, type JobLink, type JobStepOptions, type ListAttestationsParams, type ListRunsParams, MAX_BATCH_ROWS, NotFoundError, type PDFFormat, type Policy, type PolicyActivation, type PolicyActivationSignature, type PolicyActorType, type PolicyClassification, type PolicyContext, type PolicyList, type PolicyObjectType, type PolicyTestRequest, type PolicyTestResult, type PolicyWithDocument, RUN_STATUSES, type ReproducibilityContext, type RequestKeyChange, type RequestKeyPair, type RequestKeyRegistration, type RequestKeyRegistrationBody, type RequestSignature, type RequestSignatureV2, type Run, type RunStats, type RunStatus, type RunSummary, type RunsExport, type RunsExportCSV, type SearchRunsParams, type SignedRequestBody, VerdifaxClient, VerdifaxError, VerdifaxJob, type VerdifaxVersion, type VerifyDeterminismResponse, type VerifyResponse, captureEnvironment, cresReceiptHash, dcaeClosureHash, dseDispatchHash, formatProviderPayload, fromEnv, generateRequestKeyPair, policyActivationApproval, policyActivationPreimage, requestKeyChangeApproval, requestKeyChangePreimage, requestKeyRegistrationBody, requestSignaturePreimage, requestSignaturePreimageV2, signRequest, signRequestV2, validateHex64, validateJobName, validateRouteId };