@atlasent/sdk 2.10.0 → 2.12.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.
@@ -97,7 +97,7 @@ type AtlaSentDecision = "deny" | "hold" | "escalate";
97
97
  * `atlasent/docs/REVOCATION_RUNBOOK.md` for the operator-facing
98
98
  * matrix this discriminator drives.
99
99
  */
100
- type PermitOutcome = "permit_consumed" | "permit_expired" | "permit_revoked" | "permit_not_found";
100
+ type PermitOutcome = "permit_consumed" | "permit_expired" | "permit_revoked" | "permit_not_found" | "permit_signing_key_revoked";
101
101
  /**
102
102
  * Map a server-supplied `outcome` string to {@link PermitOutcome}.
103
103
  *
@@ -169,6 +169,11 @@ declare class AtlaSentDeniedError extends AtlaSentError {
169
169
  * (typo, cross-tenant lookup, or pre-issuance race).
170
170
  */
171
171
  get isNotFound(): boolean;
172
+ /**
173
+ * `true` when the permit's signing key KID appears in the
174
+ * trust-root revocation list (ADR-005 D3 R2/R3 key rotation).
175
+ */
176
+ get isSigningKeyRevoked(): boolean;
172
177
  }
173
178
  /** Initialization options for {@link AtlaSentEscalateError}. */
174
179
  interface AtlaSentEscalateErrorInit {
@@ -237,6 +242,50 @@ declare class PermitRevoked extends AtlaSentError {
237
242
  readonly revocationId: string | undefined;
238
243
  constructor(permitId: string, revocationId?: string);
239
244
  }
245
+ /**
246
+ * Initialization options for {@link BundleVerificationError}.
247
+ */
248
+ interface BundleVerificationErrorInit {
249
+ /**
250
+ * Machine-readable reason code:
251
+ * - `trust_snapshot_expired`: the snapshot's `valid_until` has passed
252
+ * and `allowExpiredSnapshot` was not set.
253
+ * - `key_revoked`: the bundle's `signing_key_id` appears in
254
+ * `revoked_keys` of the active trust snapshot.
255
+ * - `key_role_mismatch`: the signing key's `role` is not `"R3_audit"`.
256
+ */
257
+ reason: "trust_snapshot_expired" | "key_revoked" | "key_role_mismatch";
258
+ /** ISO-8601 `valid_until` of the snapshot that caused the failure. */
259
+ snapshotValidUntil?: string;
260
+ /** ISO-8601 `issued_at` of the snapshot (its fetch/pin time). */
261
+ snapshotFetchedAt?: string;
262
+ /** Whether the snapshot came from the bundled vendor files or a live refresh. */
263
+ snapshotSource?: "pinned" | "live";
264
+ /** Which key id was revoked or role-mismatched, when applicable. */
265
+ kid?: string;
266
+ }
267
+ /**
268
+ * Thrown by {@link verifyAuditBundle} / {@link verifyBundle} when the
269
+ * active trust-root snapshot is expired (ADR-005 D3) or the bundle's
270
+ * signing key is revoked / has the wrong role.
271
+ *
272
+ * This error is **always thrown** — it is never returned as a
273
+ * {@link BundleVerificationResult} because ADR-005 D3 requires that
274
+ * an expired snapshot or revoked key constitutes a hard enforcement
275
+ * action, not a soft verification failure.
276
+ *
277
+ * To opt out of fail-closed expiry (air-gap / offline use), pass
278
+ * `allowExpiredSnapshot: true` to `verifyBundle`.
279
+ */
280
+ declare class BundleVerificationError extends AtlaSentError {
281
+ name: string;
282
+ readonly reason: BundleVerificationErrorInit["reason"];
283
+ readonly snapshotValidUntil: string | undefined;
284
+ readonly snapshotFetchedAt: string | undefined;
285
+ readonly snapshotSource: "pinned" | "live" | undefined;
286
+ readonly kid: string | undefined;
287
+ constructor(init: BundleVerificationErrorInit);
288
+ }
240
289
 
241
290
  /**
242
291
  * Retry-policy helpers for the AtlaSent TypeScript SDK.
@@ -268,18 +317,18 @@ declare class PermitRevoked extends AtlaSentError {
268
317
  * It avoids thundering-herd retries from many SDK instances that hit
269
318
  * a 429 in the same window.
270
319
  *
271
- * Default schedule matches the Python SDK:
272
- * attempt 0 (1st retry): base 2 000 ms, jittered in [0, 2 000)
273
- * attempt 1 (2nd retry): base 4 000 ms, jittered in [0, 4 000)
274
- * attempt 2 (3rd retry): base 8 000 ms, jittered in [0, 8 000)
275
- * attempt 3 (4th retry): capped at 16 000 ms, jittered in [0, 16 000)
276
- * Total attempts (including initial): 4
320
+ * Default schedule:
321
+ * attempt 0 (1st retry): base 250 ms, jittered in [0, 250)
322
+ * attempt 1 (2nd retry): base 500 ms, jittered in [0, 500)
323
+ * Total attempts (including initial): 3
277
324
  */
278
325
  /**
279
326
  * Defaults for {@link RetryPolicy}.
280
327
  *
281
- * Matches the Python SDK's backoff schedule:
282
- * 2 s 4 s 8 s 16 s (4 total attempts, cap at 16 s).
328
+ * Exponential backoff with full jitter, base 250 ms, capped at 10 s:
329
+ * attempt 0 (1st retry): base 250 ms, jittered in [0, 250)
330
+ * attempt 1 (2nd retry): base 500 ms, jittered in [0, 500)
331
+ * Total attempts (including initial): 3
283
332
  */
284
333
  declare const DEFAULT_RETRY_POLICY: Required<RetryPolicy>;
285
334
  /**
@@ -720,6 +769,25 @@ interface ConsentClassProjection {
720
769
  event_count: number;
721
770
  category_counts: Partial<Record<string, number>>;
722
771
  }
772
+ /**
773
+ * Proof that a specific actor consumed a specific permit for a specific
774
+ * action_type. Pass an array of these as `completion_proofs` on an evaluate
775
+ * request to satisfy multi-actor quorum dependencies.
776
+ *
777
+ * The runtime verifies each proof via two gates (both must pass):
778
+ * 1. A `permit_uses` row exists for `permit_id` (permit was consumed).
779
+ * 2. An `execution_evaluations` row is bound to `actor_id` + `action_type`
780
+ * for the same permit (actor/action binding — Codex P1 #1148 FIX #3).
781
+ * Proofs that fail either gate are silently dropped (fail-closed).
782
+ */
783
+ interface CompletionProof {
784
+ /** The action_type (slug) that was completed by the prior actor. */
785
+ action_type: string;
786
+ /** The actor who completed the action. */
787
+ actor_id: string;
788
+ /** The permit token (or its hash) issued when the action was permitted. */
789
+ permit_id: string;
790
+ }
723
791
  /** Input to {@link AtlaSentClient.evaluate}. */
724
792
  interface EvaluateRequest {
725
793
  /** Identifier of the calling agent (e.g. "clinical-data-agent"). */
@@ -734,6 +802,57 @@ interface EvaluateRequest {
734
802
  * to keep response payloads small.
735
803
  */
736
804
  explain?: boolean;
805
+ /** Deployment environment where the action executes (e.g. `"production"`). */
806
+ environment?: string;
807
+ /** Structured resource descriptor. Prefer over embedding resource info in `context`. */
808
+ resource?: {
809
+ type: string;
810
+ id?: string;
811
+ attributes?: Record<string, unknown>;
812
+ };
813
+ /** Snapshot of the resource state before the proposed action. Enables state-transition-aware policy evaluation. */
814
+ current_state?: {
815
+ description: string;
816
+ attributes?: Record<string, unknown>;
817
+ };
818
+ /** Desired resource state after the action executes. */
819
+ proposed_state?: {
820
+ description: string;
821
+ attributes?: Record<string, unknown>;
822
+ };
823
+ /** Execution surface binding — identifies the CI/CD adapter, DB driver, or enforcement point. */
824
+ execution_binding?: {
825
+ kind: string;
826
+ adapter_version?: string;
827
+ resource_id?: string;
828
+ enforcement_point?: string;
829
+ };
830
+ /** The desired end-state the actor wants the resource to reach. Enables trajectory-aware authorization. */
831
+ desired_state?: {
832
+ description: string;
833
+ attributes?: Record<string, unknown>;
834
+ fingerprint?: string;
835
+ };
836
+ /** Actor-proposed execution path from current_state to desired_state. The engine returns an authorized_trajectory that may differ. */
837
+ proposed_trajectory?: {
838
+ steps: Array<{
839
+ step: string;
840
+ description?: string;
841
+ required: boolean;
842
+ time_limit_seconds?: number;
843
+ authorized_by?: string;
844
+ constraints?: Record<string, unknown>;
845
+ }>;
846
+ description?: string;
847
+ };
848
+ /**
849
+ * Multi-actor quorum completion proofs. Supply one entry per prior actor
850
+ * whose completed action this evaluation depends on. The runtime verifies
851
+ * each proof (consumed-permit gate + actor/action binding gate) and counts
852
+ * only valid proofs toward quorum. Absent or empty → no quorum proofs
853
+ * submitted (no behavioral change for non-quorum dependencies).
854
+ */
855
+ completion_proofs?: CompletionProof[];
737
856
  }
738
857
  /**
739
858
  * Slim permit object embedded in {@link EvaluateResponse} when the decision
@@ -844,6 +963,60 @@ interface EvaluateResponse {
844
963
  * upgraded from `engineDecision` to `envelopeDecision`.
845
964
  */
846
965
  riskEnvelope?: EvaluateRiskEnvelope;
966
+ /**
967
+ * Resolved risk class from the evaluation engine.
968
+ * One of `"critical"`, `"high"`, `"medium"`, `"low"`.
969
+ * Present when the risk envelope assigns a class.
970
+ */
971
+ riskClass?: string;
972
+ /**
973
+ * WHY this permit was issued — the authority kind and a reference to the
974
+ * authorizing entity. Present on `allow` decisions when the control plane
975
+ * attaches explicit authority provenance.
976
+ */
977
+ authorityBasis?: {
978
+ kind: "policy" | "approval" | "emergency" | "maintenance_window" | "delegation" | "quorum";
979
+ reference?: string;
980
+ grantedBy?: string;
981
+ rationale?: string;
982
+ expiresAt?: string;
983
+ };
984
+ /**
985
+ * ID of the HITL escalation auto-created by the control plane.
986
+ * Present iff `decision === "hold"`. Poll `GET /v1/escalations/{id}`
987
+ * for resolution status.
988
+ */
989
+ escalationId?: string;
990
+ /**
991
+ * Authorized execution trajectory returned when the engine approved a
992
+ * `proposed_trajectory`. Present only on `allow` decisions.
993
+ * May differ from what was proposed — the engine may add checkpoints,
994
+ * restrict steps, or tighten time limits. Follow this trajectory exactly;
995
+ * call `POST /v1/trajectory-verify` at each step to confirm on_trajectory.
996
+ */
997
+ authorized_trajectory?: {
998
+ trajectory_id: string;
999
+ steps: Array<{
1000
+ step: string;
1001
+ description?: string;
1002
+ required: boolean;
1003
+ time_limit_seconds?: number;
1004
+ authorized_by?: string;
1005
+ constraints?: Record<string, unknown>;
1006
+ expected_intermediate_state?: {
1007
+ description: string;
1008
+ attributes?: Record<string, unknown>;
1009
+ fingerprint?: string;
1010
+ };
1011
+ }>;
1012
+ description?: string;
1013
+ forbidden_states?: Array<{
1014
+ description: string;
1015
+ attributes?: Record<string, unknown>;
1016
+ fingerprint?: string;
1017
+ }>;
1018
+ expires_at: string;
1019
+ };
847
1020
  }
848
1021
  /** Per-factor contribution in a {@link EvaluateRiskEnvelope}. */
849
1022
  interface EvaluateRiskEnvelopeFactor {
@@ -931,18 +1104,13 @@ interface VerifyPermitResponse {
931
1104
  * key the client was constructed with. Returned by `GET /v1/api-key-self`.
932
1105
  *
933
1106
  * Never includes the raw key or its hash — introspection is intentionally
934
- * read-only and safe to surface in operator dashboards. Useful for:
935
- * - "which key am I?" debugging
936
- * - IP_NOT_ALLOWED failures — `clientIp` is the IP the server observed
937
- * - proactive expiry warnings — `expiresAt` is the server-stored expiry
938
- * (`null` means the key does not auto-expire)
939
- * - verifying scopes before attempting a scope-gated action
1107
+ * read-only and safe to surface in operator dashboards.
940
1108
  */
941
1109
  interface ApiKeySelfResponse {
942
1110
  /** Server-side UUID of the api_keys row for this key. */
943
1111
  keyId: string;
944
1112
  /** Organization the key belongs to. */
945
- organizationId: string;
1113
+ orgId: string;
946
1114
  /** "live" or "test" (or any future environment label the server introduces). */
947
1115
  environment: string;
948
1116
  /** Granted scopes — e.g. ["evaluate", "audit.read"]. */
@@ -967,24 +1135,16 @@ interface ApiKeySelfResponse {
967
1135
  /**
968
1136
  * Result of {@link AtlaSentClient.listAuditEvents}. Extends the raw
969
1137
  * wire page with a camelCase `rateLimit` alongside the snake_case
970
- * wire fields — the wire shape (`events`, `total`, `next_cursor`) is
971
- * untouched so callers that pass it to the offline verifier get
972
- * byte-identical behaviour.
1138
+ * wire fields.
973
1139
  */
974
1140
  interface AuditEventsResult extends AuditEventsPage {
975
- /**
976
- * Per-key rate-limit state for this request's response, parsed from
977
- * `X-RateLimit-*` headers. `null` when the server didn't emit them.
978
- */
979
1141
  rateLimit: RateLimitState | null;
980
1142
  }
981
1143
  /**
982
- * Filter accepted by {@link AtlaSentClient.createAuditExport}. Fields
983
- * are snake_case to match the server's `POST /v1-audit/exports`
984
- * request body; an empty object requests a full-org bundle.
1144
+ * Filter accepted by {@link AtlaSentClient.createAuditExport}.
985
1145
  */
986
1146
  interface AuditExportRequest {
987
- /** Comma-joined list of event types to include (e.g. `"evaluate.allow,policy.updated"`). */
1147
+ /** Comma-joined list of event types to include. */
988
1148
  types?: string;
989
1149
  /** Filter to a single actor. */
990
1150
  actor_id?: string;
@@ -994,18 +1154,9 @@ interface AuditExportRequest {
994
1154
  to?: string;
995
1155
  }
996
1156
  /**
997
- * Result of {@link AtlaSentClient.createAuditExport}. Extends the
998
- * signed bundle shape with a camelCase `rateLimit`. The signed
999
- * envelope fields (`export_id`, `org_id`, `chain_head_hash`,
1000
- * `event_count`, `signed_at`, `events`, `signature`) are preserved
1001
- * byte-for-byte so the object can be handed straight to
1002
- * `verifyAuditBundle(bundle, keys)`.
1157
+ * Result of {@link AtlaSentClient.createAuditExport}.
1003
1158
  */
1004
1159
  interface AuditExportResult extends AuditExport {
1005
- /**
1006
- * Per-key rate-limit state for this request's response, parsed from
1007
- * `X-RateLimit-*` headers. `null` when the server didn't emit them.
1008
- */
1009
1160
  rateLimit: RateLimitState | null;
1010
1161
  }
1011
1162
  /** Constructor options for {@link AtlaSentClient}. */
@@ -1030,16 +1181,24 @@ interface AtlaSentClientOptions {
1030
1181
  * Pass `{ maxAttempts: 1 }` to disable retries entirely.
1031
1182
  */
1032
1183
  retryPolicy?: RetryPolicy;
1184
+ /**
1185
+ * Base URL for the trust-root host (default: https://keys.atlasent.io/.well-known).
1186
+ * Override for air-gapped / enterprise mirror deployments.
1187
+ * Per ADR-005 D2.
1188
+ */
1189
+ trustRootUrl?: string;
1190
+ /**
1191
+ * Trust-root snapshot refresh interval in milliseconds.
1192
+ * Default: 4 hours. Floor: 5 minutes (ADR-005 D2).
1193
+ * Set to 0 to inherit the default.
1194
+ */
1195
+ trustSnapshotRefreshMs?: number;
1033
1196
  }
1034
1197
  /** Permit lifecycle status. */
1035
1198
  type PermitStatus = "issued" | "verified" | "consumed" | "expired" | "revoked";
1036
1199
  /**
1037
1200
  * Wire shape of a Permit row, returned by {@link AtlaSentClient.getPermit}
1038
- * and {@link AtlaSentClient.listPermits}. Mirrors the openapi `Permit`
1039
- * schema.
1040
- *
1041
- * Revocation fields (`revoked_at`, `revoked_by`, `revoke_reason`) are
1042
- * populated only when `status === 'revoked'`; null otherwise.
1201
+ * and {@link AtlaSentClient.listPermits}.
1043
1202
  */
1044
1203
  interface PermitRecord {
1045
1204
  id: string;
@@ -1058,27 +1217,23 @@ interface PermitRecord {
1058
1217
  signature?: string;
1059
1218
  payload_hash?: string | null;
1060
1219
  decision_id?: string | null;
1220
+ /** SHA-256 hex of the CDO that produced this permit. P1 provisional. */
1221
+ cdo_hash?: string | null;
1061
1222
  }
1062
1223
  /** Optional filters for {@link AtlaSentClient.listPermits}. */
1063
1224
  interface ListPermitsRequest {
1064
1225
  status?: PermitStatus;
1065
1226
  actorId?: string;
1066
1227
  actionType?: string;
1067
- /** ISO-8601 lower bound on `created_at`. */
1068
1228
  from?: string;
1069
- /** ISO-8601 upper bound on `created_at`. */
1070
1229
  to?: string;
1071
- /** Page size. Server max is 500; default 50. */
1072
1230
  limit?: number;
1073
- /** Pass `nextCursor` from a prior response to page forward. */
1074
1231
  cursor?: string;
1075
1232
  }
1076
1233
  /** Response from {@link AtlaSentClient.listPermits}. */
1077
1234
  interface ListPermitsResponse {
1078
1235
  permits: PermitRecord[];
1079
- /** Total matching rows ignoring `limit`/`cursor`. */
1080
1236
  total: number;
1081
- /** Pass on next call as `cursor`. Absent when no more rows. */
1082
1237
  nextCursor?: string;
1083
1238
  rateLimit: RateLimitState | null;
1084
1239
  }
@@ -1089,41 +1244,19 @@ interface GetPermitResponse {
1089
1244
  }
1090
1245
  /**
1091
1246
  * Response from {@link AtlaSentClient.checkPermitValid}.
1092
- *
1093
- * Lightweight validity snapshot returned by
1094
- * `GET /v1/permits/{permitId}/valid`. Designed for guard heartbeat
1095
- * polling — returns only the fields needed to determine whether to
1096
- * abort a running permit mid-execution (via {@link PermitRevoked}).
1097
1247
  */
1098
1248
  interface PermitValidResponse {
1099
- /** True iff the permit is currently valid (active). */
1100
1249
  valid: boolean;
1101
- /**
1102
- * Current lifecycle status of the permit.
1103
- * - `"active"` — permit is valid and in-flight.
1104
- * - `"expired"` — TTL elapsed before revocation or consumption.
1105
- * - `"revoked"` — administratively revoked (see `revocation_id`).
1106
- * - `"consumed"` — single-use permit already consumed.
1107
- */
1108
1250
  status: "active" | "expired" | "revoked" | "consumed";
1109
- /** ISO-8601 timestamp when the permit was revoked. Populated only when `status === "revoked"`. */
1110
1251
  revoked_at?: string;
1111
- /** Opaque identifier of the revocation record. Populated only when `status === "revoked"`. */
1112
1252
  revocation_id?: string;
1113
1253
  }
1114
1254
  /** Input for {@link AtlaSentClient.revokePermitById}. */
1115
1255
  interface RevokePermitByIdInput {
1116
- /** Operator-supplied free-text reason. Recorded on the permit row,
1117
- * written to the audit trail, and surfaced (truncated) on later
1118
- * verify responses. Optional but strongly encouraged. */
1119
1256
  reason?: string;
1120
1257
  }
1121
1258
  /**
1122
1259
  * Response from {@link AtlaSentClient.revokePermitById}.
1123
- *
1124
- * Returns the updated {@link PermitRecord} with `status === 'revoked'`
1125
- * and the populated `revoked_at` / `revoked_by` / `revoke_reason`
1126
- * fields.
1127
1260
  */
1128
1261
  interface RevokePermitByIdResponse {
1129
1262
  permit: PermitRecord;
@@ -1131,23 +1264,12 @@ interface RevokePermitByIdResponse {
1131
1264
  }
1132
1265
  /**
1133
1266
  * Response from {@link AtlaSentClient.verifyPermitById}.
1134
- *
1135
- * Returns the canonical verification envelope (`valid`,
1136
- * `verification_type`, `reason`, `verified_at`, `evidence`) plus the
1137
- * legacy {@link PermitRecord} fields preserved at the top level for
1138
- * backward compatibility. The envelope shape matches the unified
1139
- * verify response in atlasent-api PR #352.
1140
1267
  */
1141
1268
  interface VerifyPermitByIdResponse {
1142
- /** `true` iff the permit verified — i.e. unconsumed, unexpired, and signature OK. */
1143
1269
  valid: boolean;
1144
- /** Always `'permit'` on this surface. */
1145
1270
  verification_type: "permit";
1146
- /** Operator-readable explanation when `valid` is `false`; `null` on success. */
1147
1271
  reason: string | null;
1148
- /** Server clock at the moment verification ran. */
1149
1272
  verified_at: string;
1150
- /** Type-specific evidence — same fields as the openapi PermitVerifyEvidence schema. */
1151
1273
  evidence: {
1152
1274
  permit_id: string;
1153
1275
  status: PermitStatus;
@@ -1157,304 +1279,106 @@ interface VerifyPermitByIdResponse {
1157
1279
  payload_hash?: string | null;
1158
1280
  decision_id?: string | null;
1159
1281
  };
1160
- /** Legacy: full permit row preserved at the top level. */
1161
1282
  permit: PermitRecord;
1162
1283
  rateLimit: RateLimitState | null;
1163
1284
  }
1164
1285
  /** Input for {@link AtlaSentClient.revokePermit}. */
1165
1286
  interface RevokePermitRequest {
1166
- /** The permit ID returned by a prior evaluate() call. */
1167
1287
  permitId: string;
1168
- /** Optional human-readable reason stored in the audit log. */
1169
1288
  reason?: string;
1170
1289
  }
1171
1290
  /**
1172
1291
  * Result of {@link AtlaSentClient.revokePermit}.
1173
1292
  *
1174
1293
  * @deprecated Use {@link RevokePermitByIdResponse} via
1175
- * {@link AtlaSentClient.revokePermitById} — the canonical REST surface
1176
- * (`POST /v1/permits/{id}/revoke`) returns the full updated
1177
- * {@link PermitRecord} with `revoked_at`/`revoked_by`/`revoke_reason`
1178
- * populated, instead of the legacy `{revoked, permitId}` envelope.
1294
+ * {@link AtlaSentClient.revokePermitById}.
1179
1295
  * Will be removed in `@atlasent/sdk@3`.
1180
1296
  */
1181
1297
  interface RevokePermitResponse {
1182
- /** `true` when the permit was found and successfully revoked. */
1183
1298
  revoked: boolean;
1184
- /** Echo of the revoked permit's ID. */
1185
1299
  permitId: string;
1186
- /** ISO-8601 timestamp of when the revocation was recorded. `undefined` when not returned by the server. */
1187
1300
  revokedAt?: string | undefined;
1188
- /** Audit hash for the revocation event. `undefined` when not returned by the server. */
1189
1301
  auditHash?: string | undefined;
1190
- /** Per-key rate-limit state. `null` when the server didn't emit headers. */
1191
1302
  rateLimit: RateLimitState | null;
1192
1303
  }
1193
- /**
1194
- * One stage of a single policy's constraint evaluation.
1195
- *
1196
- * Mirrors `ConstraintTraceStage` in
1197
- * `atlasent-api/packages/types/src/index.ts`. Emitted by the rule
1198
- * engine when the request URL carries `?include=constraint_trace`.
1199
- *
1200
- * Forward-compat: extra engine-side keys are tolerated; readers
1201
- * should not assume this is a closed shape.
1202
- */
1203
1304
  interface ConstraintTraceStage {
1204
- /** Engine stage name (e.g. `"role_check"`, `"context"`). */
1205
1305
  readonly stage: string;
1206
- /** Optional rule identifier; absent for wrapper stages. */
1207
1306
  readonly rule?: string;
1208
- /** True iff this stage's predicate fired. */
1209
1307
  readonly matched: boolean;
1210
- /** Optional human-readable note from the engine. */
1211
1308
  readonly detail?: string;
1212
- /** Zero-based position within the policy's `stages` array. */
1213
1309
  readonly order: number;
1214
- /** Forward-compat: tolerate unknown engine-side keys without crashing. */
1215
1310
  readonly [key: string]: unknown;
1216
1311
  }
1217
- /**
1218
- * Per-policy block of a constraint trace.
1219
- *
1220
- * Mirrors `ConstraintTracePolicy` in
1221
- * `atlasent-api/packages/types/src/index.ts`. The handler iterates
1222
- * active policies in order until first non-allow; the policy that
1223
- * produced the outer decision has `decision !== "allow"`.
1224
- */
1225
1312
  interface ConstraintTracePolicy {
1226
- /** Stable identifier of the evaluated policy. */
1227
1313
  readonly policy_id: string;
1228
- /** Policy-level decision (`"allow"|"deny"|"hold"|"escalate"`). */
1229
1314
  readonly decision: string;
1230
- /** Engine-side fingerprint of the bundle row. */
1231
1315
  readonly fingerprint: string;
1232
- /**
1233
- * Optional engine-computed risk score from a `risk` rule clause.
1234
- * Distinct from the heuristic risk score on the outer envelope.
1235
- */
1236
1316
  readonly risk_score?: number;
1237
- /** Ordered stages produced while evaluating this policy. */
1238
1317
  readonly stages: ReadonlyArray<ConstraintTraceStage>;
1239
- /** Forward-compat: tolerate unknown engine-side keys. */
1240
1318
  readonly [key: string]: unknown;
1241
1319
  }
1242
- /**
1243
- * Top-level constraint trace returned by
1244
- * `/v1-evaluate?include=constraint_trace`.
1245
- *
1246
- * Mirrors `ConstraintTraceResponse` in
1247
- * `atlasent-api/packages/types/src/index.ts`. Present iff the
1248
- * caller requested the trace; the SDK's preflight helper always
1249
- * requests it.
1250
- */
1251
1320
  interface ConstraintTrace {
1252
- /** Per-policy blocks in evaluation order. */
1253
1321
  readonly rules_evaluated: ReadonlyArray<ConstraintTracePolicy>;
1254
- /**
1255
- * Policy id whose evaluation produced the outer decision. Equals
1256
- * the outer `matched_policy_id` on non-allow paths; `undefined` on
1257
- * a clean allow (all policies passed).
1258
- */
1259
1322
  readonly matching_policy_id?: string;
1260
- /** Forward-compat: tolerate unknown engine-side keys. */
1261
1323
  readonly [key: string]: unknown;
1262
1324
  }
1263
- /**
1264
- * Result of {@link AtlaSentClient.evaluatePreflight}.
1265
- *
1266
- * Wraps the regular {@link EvaluateResponse} plus the
1267
- * {@link ConstraintTrace} returned when the request URL carries
1268
- * `?include=constraint_trace`. The whole point of preflight is to
1269
- * surface which stages / policies WOULD fire BEFORE pushing the
1270
- * request onto an approval queue, so workflows can reject trivially
1271
- * defective requests at submission time and only forward viable
1272
- * requests to a human reviewer.
1273
- *
1274
- * `constraintTrace` is `null` on responses from older atlasent-api
1275
- * deployments that do not echo the trace — forward-compatible
1276
- * degradation.
1277
- */
1278
1325
  interface EvaluatePreflightResponse {
1279
- /** The regular evaluate response (decision, permitId, ...). */
1280
1326
  readonly evaluation: EvaluateResponse;
1281
- /**
1282
- * The constraint trace, or `null` when the server omitted it
1283
- * (older atlasent-api version).
1284
- */
1285
1327
  readonly constraintTrace: ConstraintTrace | null;
1286
1328
  }
1287
- /**
1288
- * Options for {@link AtlaSentClient.protectStream}.
1289
- *
1290
- * All fields are optional; defaults are used when omitted.
1291
- */
1292
1329
  interface StreamOptions {
1293
- /**
1294
- * Optional abort signal to cancel the stream from the caller side.
1295
- */
1296
1330
  signal?: AbortSignal;
1297
- /**
1298
- * Per-event timeout in milliseconds: if no SSE event arrives within
1299
- * this window the stream throws {@link StreamTimeoutError}.
1300
- * Defaults to 30 000 ms (30 s). Pass `0` to disable.
1301
- */
1302
1331
  timeoutMs?: number;
1303
- /**
1304
- * Maximum reconnection attempts on network drop before the stream
1305
- * gives up and throws. Defaults to 3.
1306
- */
1307
1332
  maxRetries?: number;
1308
1333
  }
1309
- /** A policy decision emitted mid-stream. */
1310
1334
  interface StreamDecisionEvent {
1311
1335
  type: "decision";
1312
- /**
1313
- * Policy decision — canonical 4-value lowercase vocabulary:
1314
- * `"allow"`, `"deny"`, `"hold"`, or `"escalate"`.
1315
- *
1316
- * Previously emitted `"ALLOW"` / `"DENY"` (uppercase, 2-value);
1317
- * now unified with `decision_canonical`.
1318
- *
1319
- * @deprecated Read `decision_canonical` instead for forward-compatible
1320
- * branching. Both fields now carry the same value. Will be
1321
- * removed/changed in `@atlasent/sdk@3`.
1322
- */
1323
1336
  decision: Decision;
1324
- /**
1325
- * Canonical 4-value decision, byte-identical to the wire.
1326
- * One of `"allow"`, `"deny"`, `"hold"`, `"escalate"`.
1327
- */
1328
1337
  decision_canonical: DecisionCanonical;
1329
- /** Opaque permit identifier for a final allow. Pass to verifyPermit. */
1330
1338
  permitId: string;
1331
- /** Human-readable explanation from the policy engine. */
1332
1339
  reason: string;
1333
- /** Audit hash bound to this decision. */
1334
1340
  auditHash: string;
1335
- /** ISO-8601 timestamp of the decision. */
1336
1341
  timestamp: string;
1337
- /** When true the stream will emit done and close after this event. */
1338
1342
  isFinal: boolean;
1339
1343
  }
1340
- /** An intermediate progress hint emitted before the final decision. */
1341
1344
  interface StreamProgressEvent {
1342
1345
  type: "progress";
1343
- /** Human-readable stage name (e.g. "policy_loading", "context_enrichment"). */
1344
1346
  stage: string;
1345
- /** Additional server-defined fields — forward-compat, do not rely on shape. */
1346
1347
  [key: string]: unknown;
1347
1348
  }
1348
- /** Union of all events yielded by {@link AtlaSentClient.protectStream}. */
1349
1349
  type StreamEvent = StreamDecisionEvent | StreamProgressEvent;
1350
- /**
1351
- * A single item in a {@link AtlaSentClient.evaluateBatch} call.
1352
- * Same shape as {@link EvaluateRequest}.
1353
- */
1354
1350
  interface BatchEvalItem {
1355
- /** Identifier of the calling agent. */
1356
1351
  agent: string;
1357
- /** The action being authorized. */
1358
1352
  action: string;
1359
- /** Arbitrary policy context. */
1360
1353
  context?: Record<string, unknown>;
1361
1354
  }
1362
- /**
1363
- * Per-item result in an {@link EvaluateBatchResponse}.
1364
- *
1365
- * Success items carry `decision`, `decisionId`, `permitToken`, `auditHash`,
1366
- * and `timestamp`. Error items (when the per-item RPC layer failed) carry
1367
- * only `index`, `error`, and optionally `message`.
1368
- */
1369
1355
  interface EvaluateBatchResultItem {
1370
- /** 0-based position matching the input order. */
1371
1356
  index: number;
1372
- /**
1373
- * Policy decision for this item. Present on success items.
1374
- * `"allow"`, `"deny"`, `"hold"`, or `"escalate"`.
1375
- */
1376
1357
  decision?: DecisionCanonical;
1377
- /** Server-assigned permit / decision identifier. */
1378
1358
  decisionId?: string;
1379
- /** Opaque permit token (allow decisions only). Pass to verifyPermit(). */
1380
1359
  permitToken?: string | null;
1381
- /** Machine-readable denial / hold reason. */
1382
1360
  reason?: string;
1383
- /** Hash-chained audit-trail entry. */
1384
1361
  auditHash?: string;
1385
- /** ISO-8601 decision timestamp. */
1386
1362
  timestamp?: string;
1387
- /** Error code when the item itself failed at the RPC layer. */
1388
1363
  error?: string;
1389
- /** Human-readable detail when `error` is set. */
1390
1364
  message?: string;
1391
1365
  }
1392
- /**
1393
- * Response from {@link AtlaSentClient.evaluateBatch}.
1394
- *
1395
- * - `items` is in the same order as the input `requests` array.
1396
- * - `partial: true` means at least one item errored at the RPC layer
1397
- * (not a policy deny — those are surfaced via `decision: "deny"` on
1398
- * the item). Check `item.error` on items without a `decision`.
1399
- * - `replayed: true` means the response was served from the idempotency
1400
- * cache (a prior call with the same `batchId` completed within 24 h).
1401
- */
1402
1366
  interface BatchEvalResponse {
1403
- /** Server-assigned (or caller-supplied) batch identifier. */
1404
1367
  batchId: string;
1405
- /** Per-item results, in input order. */
1406
1368
  items: EvaluateBatchResultItem[];
1407
- /** `true` when at least one item failed at the RPC layer. */
1408
1369
  partial: boolean;
1409
- /** `true` when served from the idempotency cache. */
1410
1370
  replayed?: boolean;
1411
- /** Rate-limit state from the batch response headers. */
1412
1371
  rateLimit: RateLimitState | null;
1413
1372
  }
1414
- /**
1415
- * Options for {@link AtlaSentClient.subscribeDecisions}.
1416
- */
1417
1373
  interface SubscribeDecisionsOptions {
1418
- /**
1419
- * Filter to specific event types (e.g. `["evaluate.allow", "evaluate.deny"]`).
1420
- * Omit to receive all types.
1421
- */
1422
1374
  types?: string[];
1423
- /** Filter to a specific actor ID. */
1424
1375
  actorId?: string;
1425
- /**
1426
- * Resume from a prior event. Pass the `id` of the last received event.
1427
- * The server replays everything after that sequence position, then
1428
- * transitions to live polling.
1429
- */
1430
1376
  lastEventId?: string;
1431
- /**
1432
- * Maximum session duration in seconds. The server emits `session_end`
1433
- * and closes after this window; the caller should reconnect with the
1434
- * last received `lastEventId`. Defaults to 1800 (30 min), max 3600 (1 h).
1435
- */
1436
1377
  maxSeconds?: number;
1437
- /** Abort signal to cancel the stream. */
1438
1378
  signal?: AbortSignal;
1439
1379
  }
1440
- /**
1441
- * A single event from {@link AtlaSentClient.subscribeDecisions}.
1442
- *
1443
- * The `type` field maps to the audit-event type emitted by the server
1444
- * (e.g. `"evaluate.allow"`, `"evaluate.deny"`, `"permit.verified"`).
1445
- * `"heartbeat"` is a synthetic type emitted by the SDK — not a server
1446
- * event — indicating the server sent a keepalive ping.
1447
- * `"session_end"` signals the server-side max-seconds limit was reached;
1448
- * reconnect with `lastEventId` to continue.
1449
- */
1450
1380
  interface DecisionStreamEvent {
1451
- /** Stable server-assigned ID. Pass as `lastEventId` to resume. */
1452
1381
  id?: string;
1453
- /**
1454
- * Audit-event type, e.g. `"evaluate.allow"`, `"evaluate.deny"`,
1455
- * `"evaluate.hold"`, `"permit.verified"`, `"permit.revoked"`,
1456
- * `"heartbeat"`, `"session_end"`.
1457
- */
1458
1382
  type: string;
1459
1383
  decision?: DecisionCanonical;
1460
1384
  actorId?: string;
@@ -1466,6 +1390,178 @@ interface DecisionStreamEvent {
1466
1390
  occurredAt?: string;
1467
1391
  }
1468
1392
 
1393
+ /**
1394
+ * Override types — wire shapes for `/v1/overrides`.
1395
+ *
1396
+ * Overrides allow an authorized actor to bypass a deny decision for a
1397
+ * specific evaluation. They must be approved before they take effect
1398
+ * and can be revoked at any time.
1399
+ *
1400
+ * Mirrors `api/src/schemas/overrides.ts` in atlasent-control-plane.
1401
+ */
1402
+ /**
1403
+ * Lifecycle status of an override request.
1404
+ *
1405
+ * - `pending` — created, waiting for approval
1406
+ * - `approved` — approved and active; the evaluation's deny is lifted
1407
+ * - `revoked` — manually revoked
1408
+ * - `expired` — TTL elapsed before revocation
1409
+ */
1410
+ type OverrideStatus = "pending" | "approved" | "revoked" | "expired";
1411
+ /**
1412
+ * The event types that can appear on an override's event log.
1413
+ */
1414
+ type OverrideEventType = "created" | "approved" | "revoked";
1415
+ /**
1416
+ * Canonical Override domain object returned by the API.
1417
+ *
1418
+ * All timestamps are ISO-8601 UTC strings. Nullable fields are `null`
1419
+ * rather than omitted so wire shapes are stable.
1420
+ */
1421
+ interface OverrideV1 {
1422
+ id: string;
1423
+ orgId: string;
1424
+ /** The evaluation ID this override applies to. */
1425
+ evaluationId: string;
1426
+ /** Human-readable justification provided at creation time. */
1427
+ reason: string;
1428
+ status: OverrideStatus;
1429
+ /** Actor who requested the override. */
1430
+ requestedBy: string;
1431
+ /** Actor who approved the override, or `null` if not yet approved. */
1432
+ approvedBy: string | null;
1433
+ /** Actor who revoked the override, or `null` if not revoked. */
1434
+ revokedBy: string | null;
1435
+ /** ISO-8601 creation timestamp. */
1436
+ createdAt: string;
1437
+ /** ISO-8601 approval timestamp, or `null`. */
1438
+ approvedAt: string | null;
1439
+ /** ISO-8601 revocation timestamp, or `null`. */
1440
+ revokedAt: string | null;
1441
+ /** ISO-8601 expiry timestamp, or `null` if no TTL was set. */
1442
+ expiresAt: string | null;
1443
+ /** Arbitrary key/value metadata attached at creation. `null` when none. */
1444
+ metadata: Record<string, unknown> | null;
1445
+ }
1446
+ /**
1447
+ * Paginated list of overrides.
1448
+ */
1449
+ interface OverrideListResponse {
1450
+ items: OverrideV1[];
1451
+ /** Opaque cursor for the next page. `null` when there are no more results. */
1452
+ nextCursor: string | null;
1453
+ }
1454
+ /**
1455
+ * Input for `POST /v1/overrides` — request a new override.
1456
+ */
1457
+ interface CreateOverrideRequest {
1458
+ /** Human-readable justification. Required; max 2000 characters. */
1459
+ reason: string;
1460
+ /** The evaluation ID to override. */
1461
+ evaluationId: string;
1462
+ /** Lifetime in seconds. Defaults to 3600. Max 604800 (7 days). */
1463
+ ttlSeconds?: number;
1464
+ /** Arbitrary metadata to attach to the override record. */
1465
+ metadata?: Record<string, unknown>;
1466
+ }
1467
+ /**
1468
+ * Audit event appended to an override's event log on every state mutation.
1469
+ */
1470
+ interface OverrideEvent {
1471
+ id: string;
1472
+ overrideId: string;
1473
+ orgId: string;
1474
+ /** Actor who caused this event. */
1475
+ actorId: string;
1476
+ type: OverrideEventType;
1477
+ /** ISO-8601 timestamp. */
1478
+ at: string;
1479
+ /** Event-specific payload. `null` when none. */
1480
+ payload: Record<string, unknown> | null;
1481
+ }
1482
+ /**
1483
+ * Response for `GET /v1/overrides/:id/events`.
1484
+ */
1485
+ interface OverrideEventsResponse {
1486
+ items: OverrideEvent[];
1487
+ }
1488
+
1489
+ /**
1490
+ * Compliance evidence types — wire shapes for `v1-compliance-evidence`.
1491
+ *
1492
+ * Supports on-demand SOC 2 Type II control evidence collection. The
1493
+ * same run shape is used for ISO 27001, GDPR, and HIPAA; control IDs
1494
+ * differ per framework.
1495
+ */
1496
+ type ComplianceFramework = "soc2" | "iso27001" | "gdpr" | "hipaa";
1497
+ type EvidenceControlStatus = "pass" | "gap" | "finding";
1498
+ type ComplianceRunStatus = "pending" | "running" | "completed" | "failed";
1499
+ /**
1500
+ * A single evaluated control within an evidence run.
1501
+ * `evidence` is a free-form object whose keys are framework-specific
1502
+ * metric names (e.g. `mfa_enforced_policies`, `audit_events_last_30d`).
1503
+ */
1504
+ interface EvidenceControl {
1505
+ control_id: string;
1506
+ title: string;
1507
+ status: EvidenceControlStatus;
1508
+ evidence: Record<string, unknown>;
1509
+ }
1510
+ interface ComplianceEvidenceSummary {
1511
+ total: number;
1512
+ pass: number;
1513
+ gap: number;
1514
+ finding: number;
1515
+ }
1516
+ interface ComplianceEvidenceRun {
1517
+ id: string;
1518
+ org_id: string;
1519
+ framework: ComplianceFramework;
1520
+ period_start: string;
1521
+ period_end: string;
1522
+ status: ComplianceRunStatus;
1523
+ controls: EvidenceControl[];
1524
+ summary: ComplianceEvidenceSummary | null;
1525
+ applied_by: string | null;
1526
+ created_at: string;
1527
+ }
1528
+ interface TriggerEvidenceRunRequest {
1529
+ framework: ComplianceFramework;
1530
+ /** ISO 8601 date string; defaults to 30 days ago on the server. */
1531
+ period_start?: string;
1532
+ /** ISO 8601 date string; defaults to now on the server. */
1533
+ period_end?: string;
1534
+ }
1535
+ interface TriggerEvidenceRunResponse {
1536
+ run: ComplianceEvidenceRun;
1537
+ }
1538
+ interface ListEvidenceRunsResponse {
1539
+ runs: ComplianceEvidenceRun[];
1540
+ }
1541
+ /**
1542
+ * SOC 2 control IDs evaluated by `v1-compliance-evidence`.
1543
+ *
1544
+ * | ID | Area |
1545
+ * |--------|------|
1546
+ * | CC6.1 | MFA enforcement |
1547
+ * | CC6.3 | Periodic access reviews |
1548
+ * | CC7.2 | Audit trail completeness |
1549
+ * | CC8.1 | Change management / HITL |
1550
+ * | CC3.2 | Policy violations |
1551
+ */
1552
+ type SOC2ControlId = "CC6.1" | "CC6.3" | "CC7.2" | "CC8.1" | "CC3.2";
1553
+ /**
1554
+ * Returns `true` when every control in the run has `pass` or `gap`
1555
+ * status (no `finding`). A `gap` means a control is partially met;
1556
+ * a `finding` is a blocking deficiency that requires remediation.
1557
+ */
1558
+ declare function evidenceRunPasses(run: ComplianceEvidenceRun): boolean;
1559
+ /**
1560
+ * Returns controls that do not have `pass` status, sorted so
1561
+ * `finding` controls appear before `gap` controls.
1562
+ */
1563
+ declare function nonPassingControls(run: ComplianceEvidenceRun): EvidenceControl[];
1564
+
1469
1565
  /**
1470
1566
  * Evidence Engine — per-decision proof artifacts, "why" traces, and
1471
1567
  * compliance-ready bundles.
@@ -1648,6 +1744,143 @@ interface DecisionReceipt {
1648
1744
  */
1649
1745
  payload: DecisionReceiptPayload;
1650
1746
  }
1747
+ /** Coverage summary for one compliance control within a bundle. */
1748
+ interface ComplianceControlCoverage {
1749
+ framework: ComplianceFramework;
1750
+ control_id: string;
1751
+ title: string;
1752
+ /** `true` when this bundle provides sufficient evidence for the control. */
1753
+ covered: boolean;
1754
+ /** Evidence kinds present in the bundle that map to this control. */
1755
+ evidence_kinds: string[];
1756
+ }
1757
+ /**
1758
+ * A compliance-ready evidence bundle for a single protected action.
1759
+ *
1760
+ * Contains everything an auditor needs to verify the authorization
1761
+ * decision without querying the API:
1762
+ *
1763
+ * - The signed {@link DecisionReceipt}
1764
+ * - The "why" trace (why allowed / why denied)
1765
+ * - Audit events from the decision window
1766
+ * - Permit chain (when the decision was `"allow"`)
1767
+ * - Active overrides that influenced the decision
1768
+ * - Per-control SOC 2 / compliance coverage map
1769
+ *
1770
+ * `bundle_hash` is SHA-256 of `JSON.stringify(bundle)` with
1771
+ * `bundle_hash` omitted, computed by `computeBundleHash()`. Use it
1772
+ * to verify the bundle was not modified after assembly.
1773
+ */
1774
+ interface ActionEvidenceBundle {
1775
+ /** Wire format version. */
1776
+ v: 1;
1777
+ bundle_id: string;
1778
+ evaluation_id: string;
1779
+ org_id: string;
1780
+ action: string;
1781
+ actor: string;
1782
+ decision: DecisionCanonical;
1783
+ receipt: DecisionReceipt;
1784
+ why_trace: WhyTrace | null;
1785
+ /** Audit events from the evaluation window related to this action. */
1786
+ audit_events: AuditEvent[];
1787
+ /** Permit chain when the decision was `"allow"`. */
1788
+ permit_chain: PermitRecord[];
1789
+ /** Active overrides that influenced the decision. */
1790
+ overrides: OverrideV1[];
1791
+ compliance_controls: ComplianceControlCoverage[];
1792
+ generated_at: string;
1793
+ /** SHA-256 hex of canonical JSON of this bundle (sans this field). */
1794
+ bundle_hash: string;
1795
+ }
1796
+ /**
1797
+ * Convert a raw `ConstraintTrace` (from `?include=constraint_trace`)
1798
+ * into a structured {@link WhyTrace} with a human-readable summary.
1799
+ *
1800
+ * Safe to call with `trace === null` — returns a minimal trace with
1801
+ * the decision and a generic summary derived from `reasons`.
1802
+ *
1803
+ * ```ts
1804
+ * import { buildWhyTrace } from "@atlasent/sdk";
1805
+ *
1806
+ * const preflight = await client.evaluatePreflight({ agent, action, context });
1807
+ * const why = buildWhyTrace(
1808
+ * preflight.evaluation.decision_canonical,
1809
+ * preflight.evaluation.reasons,
1810
+ * preflight.constraintTrace,
1811
+ * );
1812
+ * console.log(why.summary);
1813
+ * // "Denied at stage 'role_check': actor lacks deploy role"
1814
+ * ```
1815
+ */
1816
+ declare function buildWhyTrace(decision: DecisionCanonical, reasons: readonly string[], trace: ConstraintTrace | null): WhyTrace;
1817
+ /**
1818
+ * Compute SHA-256 hex of the recursively key-sorted canonical JSON of
1819
+ * `context`. Used as `context_hash` on a `DecisionReceipt` so the
1820
+ * original evaluate context can be independently verified offline.
1821
+ */
1822
+ declare function computeContextHash(context: Record<string, unknown>): Promise<string>;
1823
+ /**
1824
+ * Assemble a {@link DecisionReceiptPayload} — the canonical object
1825
+ * that is serialised and signed. Field insertion order is fixed;
1826
+ * do NOT reorder the fields below.
1827
+ */
1828
+ declare function buildDecisionReceiptPayload(args: {
1829
+ receipt_id: string;
1830
+ evaluation_id: string;
1831
+ org_id: string;
1832
+ decision: DecisionCanonical;
1833
+ action: string;
1834
+ actor: string;
1835
+ resource_type?: string | null;
1836
+ resource_id?: string | null;
1837
+ reasons: readonly string[];
1838
+ why_summary: string;
1839
+ permit_id?: string | null;
1840
+ permit_hash?: string | null;
1841
+ audit_hash: string;
1842
+ context_hash: string;
1843
+ issued_at: string;
1844
+ expires_at?: string | null;
1845
+ }): DecisionReceiptPayload;
1846
+ /**
1847
+ * HMAC-SHA256 sign a {@link DecisionReceiptPayload}. Returns the
1848
+ * hex-encoded MAC. Store as `receipt.signature` with
1849
+ * `algorithm: "hmac-sha256"`.
1850
+ *
1851
+ * Uses `crypto.subtle` (browser / Node 20+ / Cloudflare) or falls
1852
+ * back to `node:crypto` on older Node runtimes.
1853
+ */
1854
+ declare function signDecisionReceiptHmac(payload: DecisionReceiptPayload, secret: string): Promise<string>;
1855
+ /**
1856
+ * Verify an HMAC-SHA256-signed {@link DecisionReceipt} offline.
1857
+ * Returns `false` (does not throw) on any verification failure.
1858
+ *
1859
+ * Callers MUST reject receipts where `receipt.algorithm !== "hmac-sha256"`.
1860
+ */
1861
+ declare function verifyDecisionReceiptHmac(receipt: DecisionReceipt, secret: string): Promise<boolean>;
1862
+ /**
1863
+ * Compute SHA-256 hex of `JSON.stringify(bundle)` with `bundle_hash`
1864
+ * omitted. Store as `bundle.bundle_hash` after assembly.
1865
+ *
1866
+ * An external verifier can reproduce this value independently to
1867
+ * confirm the bundle was not modified after export.
1868
+ */
1869
+ declare function computeBundleHash(bundle: Omit<ActionEvidenceBundle, "bundle_hash">): Promise<string>;
1870
+ /**
1871
+ * Return the SOC 2 controls covered by a single authorization decision,
1872
+ * given what the bundle contains. Suitable for populating
1873
+ * `ActionEvidenceBundle.compliance_controls`.
1874
+ *
1875
+ * For ISO 27001 / GDPR / HIPAA coverage use the `@atlasent/evidence-bundle`
1876
+ * package's `buildEvidenceBundle()` which handles multi-framework mapping.
1877
+ */
1878
+ declare function soc2ControlCoverageForDecision(opts: {
1879
+ decision: DecisionCanonical;
1880
+ hasPermitChain: boolean;
1881
+ hasAuditEvents: boolean;
1882
+ hasOverrides: boolean;
1883
+ }): ComplianceControlCoverage[];
1651
1884
 
1652
1885
  /** Input to {@link protect}. Same shape as `EvaluateRequest`. */
1653
1886
  interface ProtectRequest {
@@ -1773,4 +2006,4 @@ interface ProtectWithEvidenceOptions {
1773
2006
  */
1774
2007
  declare function protectWithEvidence(request: ProtectRequest, opts?: ProtectWithEvidenceOptions): Promise<PermitWithEvidence>;
1775
2008
 
1776
- export { type ConstraintTrace as $, AtlaSentDeniedError as A, type BatchEvalItem as B, protect as C, type DecisionCanonical as D, type EvaluateRequest as E, deployGate as F, type GetPermitResponse as G, configure as H, type AtlaSentDecision as I, type AtlaSentDeniedErrorInit as J, type AtlaSentErrorCode as K, type ListPermitsRequest as L, type AtlaSentErrorInit as M, AtlaSentEscalateError as N, type AtlaSentEscalateErrorInit as O, type Permit as P, type AuditDecision as Q, type RateLimitState as R, type SubscribeDecisionsOptions as S, type AuditEvent as T, type AuditEventsPage as U, type VerifyPermitRequest as V, type AuditExport as W, type AuditExportSignatureStatus as X, type BvsSnapshot as Y, type ConfigureOptions as Z, type ConsentClassProjection as _, AtlaSentError as a, type ConstraintTracePolicy as a0, type ConstraintTraceStage as a1, DEFAULT_RETRY_POLICY as a2, DEPLOYMENT_PRODUCTION_ACTION as a3, DEPLOY_GATE_CODES as a4, type Decision as a5, type DeployGateContext as a6, type DeployGateDenyCode as a7, type DeployGateEvidence as a8, type DeployOverrideClaim as a9, type DeployPermitClaim as aa, type EvaluateBatchResultItem as ab, type EvaluateResponsePermit as ac, type EvaluateRiskEnvelope as ad, type EvaluateRiskEnvelopeFactor as ae, PRODUCTION_DEPLOY_ACTION as af, type PermitOutcome as ag, type PermitRecord as ah, PermitRevoked as ai, type PermitStatus as aj, type PermitWithEvidence as ak, type ProtectWithEvidenceOptions as al, type RetryPolicy as am, type StreamDecisionEvent as an, StreamParseError as ao, type StreamProgressEvent as ap, StreamTimeoutError as aq, computeBackoffMs as ar, hasAttemptsLeft as as, isRetryable as at, mergePolicy as au, normalizePermitOutcome as av, protectWithEvidence as aw, type ProtectRequest as b, type AtlaSentClientOptions as c, type EvaluateResponse as d, type BatchEvalResponse as e, type DecisionStreamEvent as f, type EvaluatePreflightResponse as g, type VerifyPermitResponse as h, type DeployGateRequest as i, type DeployGateResponse as j, type RevokePermitRequest as k, type RevokePermitResponse as l, type RevokePermitByIdInput as m, type RevokePermitByIdResponse as n, type VerifyPermitByIdResponse as o, type PermitValidResponse as p, type ListPermitsResponse as q, type ApiKeySelfResponse as r, type AuditEventsQuery as s, type AuditEventsResult as t, type AuditExportRequest as u, type AuditExportResult as v, type StreamOptions as w, type StreamEvent as x, type DecisionReceipt as y, type DecisionReceiptAlgorithm as z };
2009
+ export { BundleVerificationError as $, AtlaSentDeniedError as A, type BatchEvalItem as B, type ComplianceEvidenceRun as C, type DecisionCanonical as D, type EvaluateRequest as E, protect as F, type GetPermitResponse as G, deployGate as H, configure as I, type ActionEvidenceBundle as J, type AtlaSentDecision as K, type ListPermitsRequest as L, type AtlaSentDeniedErrorInit as M, type AtlaSentErrorCode as N, type OverrideV1 as O, type Permit as P, type AtlaSentErrorInit as Q, type RateLimitState as R, type SubscribeDecisionsOptions as S, AtlaSentEscalateError as T, type AtlaSentEscalateErrorInit as U, type VerifyPermitRequest as V, type AuditDecision as W, type AuditEvent as X, type AuditEventsPage as Y, type AuditExport as Z, type AuditExportSignatureStatus as _, AtlaSentError as a, protectWithEvidence as a$, type BvsSnapshot as a0, type CompletionProof as a1, type ComplianceControlCoverage as a2, type ComplianceEvidenceSummary as a3, type ComplianceFramework as a4, type ComplianceRunStatus as a5, type ConfigureOptions as a6, type ConsentClassProjection as a7, type ConstraintTrace as a8, type ConstraintTracePolicy as a9, type PermitRecord as aA, PermitRevoked as aB, type PermitStatus as aC, type PermitWithEvidence as aD, type ProtectWithEvidenceOptions as aE, type RetryPolicy as aF, type SOC2ControlId as aG, type StreamDecisionEvent as aH, StreamParseError as aI, type StreamProgressEvent as aJ, StreamTimeoutError as aK, type TriggerEvidenceRunRequest as aL, type TriggerEvidenceRunResponse as aM, type WhyPolicyEvaluation as aN, type WhyStage as aO, type WhyTrace as aP, buildDecisionReceiptPayload as aQ, buildWhyTrace as aR, computeBackoffMs as aS, computeBundleHash as aT, computeContextHash as aU, evidenceRunPasses as aV, hasAttemptsLeft as aW, isRetryable as aX, mergePolicy as aY, nonPassingControls as aZ, normalizePermitOutcome as a_, type ConstraintTraceStage as aa, type CreateOverrideRequest as ab, DEFAULT_RETRY_POLICY as ac, DEPLOYMENT_PRODUCTION_ACTION as ad, DEPLOY_GATE_CODES as ae, type Decision as af, type DecisionReceiptPayload as ag, type DeployGateContext as ah, type DeployGateDenyCode as ai, type DeployGateEvidence as aj, type DeployOverrideClaim as ak, type DeployPermitClaim as al, type EvaluateBatchResultItem as am, type EvaluateResponsePermit as an, type EvaluateRiskEnvelope as ao, type EvaluateRiskEnvelopeFactor as ap, type EvidenceControl as aq, type EvidenceControlStatus as ar, type ListEvidenceRunsResponse as as, type OverrideEvent as at, type OverrideEventType as au, type OverrideEventsResponse as av, type OverrideListResponse as aw, type OverrideStatus as ax, PRODUCTION_DEPLOY_ACTION as ay, type PermitOutcome as az, type ProtectRequest as b, signDecisionReceiptHmac as b0, soc2ControlCoverageForDecision as b1, verifyDecisionReceiptHmac as b2, type AtlaSentClientOptions as c, type EvaluateResponse as d, type BatchEvalResponse as e, type DecisionStreamEvent as f, type EvaluatePreflightResponse as g, type VerifyPermitResponse as h, type DeployGateRequest as i, type DeployGateResponse as j, type RevokePermitRequest as k, type RevokePermitResponse as l, type RevokePermitByIdInput as m, type RevokePermitByIdResponse as n, type VerifyPermitByIdResponse as o, type PermitValidResponse as p, type ListPermitsResponse as q, type ApiKeySelfResponse as r, type AuditEventsQuery as s, type AuditEventsResult as t, type AuditExportRequest as u, type AuditExportResult as v, type StreamOptions as w, type StreamEvent as x, type DecisionReceipt as y, type DecisionReceiptAlgorithm as z };