@atlasent/sdk 1.5.0 → 2.5.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.cts CHANGED
@@ -1,599 +1,4035 @@
1
+ import { R as RateLimitState, c as AtlaSentClientOptions, E as EvaluateRequest, d as EvaluateResponse, e as EvaluatePreflightResponse, V as VerifyPermitRequest, f as VerifyPermitResponse, D as DeployGateRequest, g as DeployGateResponse, h as RevokePermitRequest, i as RevokePermitResponse, j as RevokePermitByIdInput, k as RevokePermitByIdResponse, l as VerifyPermitByIdResponse, G as GetPermitResponse, m as PermitValidResponse, L as ListPermitsRequest, n as ListPermitsResponse, o as ApiKeySelfResponse, p as AuditEventsQuery, q as AuditEventsResult, r as AuditExportRequest, s as AuditExportResult, S as StreamOptions, t as StreamEvent, b as ProtectRequest, P as Permit, a as AtlaSentError, u as protect, v as deployGate, w as configure, A as AtlaSentDeniedError } from './protect-DiRVfVLq.cjs';
2
+ export { x as AtlaSentDecision, y as AtlaSentDeniedErrorInit, z as AtlaSentErrorCode, B as AtlaSentErrorInit, C as AtlaSentEscalateError, F as AtlaSentEscalateErrorInit, H as AuditDecision, I as AuditEvent, J as AuditEventsPage, K as AuditExport, M as AuditExportSignatureStatus, N as ConfigureOptions, O as ConstraintTrace, Q as ConstraintTracePolicy, T as ConstraintTraceStage, U as DEFAULT_RETRY_POLICY, W as DEPLOYMENT_PRODUCTION_ACTION, X as DEPLOY_GATE_CODES, Y as Decision, Z as DecisionCanonical, _ as DeployGateContext, $ as DeployGateDenyCode, a0 as DeployGateEvidence, a1 as DeployOverrideClaim, a2 as DeployPermitClaim, a3 as EvaluateResponsePermit, a4 as PRODUCTION_DEPLOY_ACTION, a5 as PermitOutcome, a6 as PermitRecord, a7 as PermitRevoked, a8 as PermitStatus, a9 as RetryPolicy, aa as StreamDecisionEvent, ab as StreamParseError, ac as StreamProgressEvent, ad as StreamTimeoutError, ae as computeBackoffMs, af as hasAttemptsLeft, ag as isRetryable, ah as mergePolicy, ai as normalizePermitOutcome } from './protect-DiRVfVLq.cjs';
1
3
  import { webcrypto } from 'node:crypto';
2
- import { p as protect, c as configure, a as AtlaSentError, A as AtlaSentDeniedError } from './protect-BKxcoR_2.cjs';
3
- export { d as AtlaSentDecision, e as AtlaSentDeniedErrorInit, f as AtlaSentErrorCode, g as AtlaSentErrorInit, C as ConfigureOptions, P as Permit, b as ProtectRequest } from './protect-BKxcoR_2.cjs';
4
4
 
5
5
  /**
6
- * Shared audit wire types the `/v1/audit/*` HTTP surface.
6
+ * Dual-shape input bridge for the v2.0.0 wire format change.
7
7
  *
8
- * Source of truth: `atlasent-api/supabase/functions/v1-audit/index.ts`
9
- * (the edge function that serves `GET /v1/audit/events`,
10
- * `POST /v1/audit/exports`, and `POST /v1/audit/verify`). The docstring
11
- * at the top of that file describes these shapes. Keep this module in
12
- * lockstep with it; `test/audit-types.test.ts` contains type-level
13
- * assertions against the field set to make drift obvious.
8
+ * The v2.0.0 wire format renamed the evaluate request fields:
9
+ * OLD: { action, agent, context, api_key }
10
+ * NEW: { action_type, actor_id, context }
14
11
  *
15
- * Fields are snake_case because that is what the server emits on the
16
- * wire unlike the evaluate / verify-permit types in `./types.ts`,
17
- * which use camelCase on the SDK side and translate at the client
18
- * boundary, the audit surface is intentionally wire-identical so that
19
- * signed export bundles round-trip byte-for-byte through verifiers.
12
+ * And the response fields:
13
+ * OLD: { permitted, decision_id }
14
+ * NEW: { decision, permit_token }
15
+ *
16
+ * TypeScript callers on the old v1.x request shape receive a
17
+ * deprecation warning and are transparently upgraded to the new
18
+ * shape. The response compat bridge normalises the legacy
19
+ * `permitted` boolean to `decision === "allow"`.
20
+ *
21
+ * Both shims will be removed in v3.0.0.
22
+ */
23
+ /** Legacy v1.x evaluate request shape. */
24
+ interface LegacyEvaluateRequest {
25
+ action?: string;
26
+ agent?: string;
27
+ context?: Record<string, unknown>;
28
+ }
29
+ /** v2.0 evaluate request shape (canonical wire format). */
30
+ interface V2EvaluateRequest {
31
+ action_type: string;
32
+ actor_id: string;
33
+ context?: Record<string, unknown>;
34
+ }
35
+ /**
36
+ * Normalise an evaluate request from either the legacy v1.x shape
37
+ * (`action` / `agent`) or the current v2.0 shape (`action_type` /
38
+ * `actor_id`) into the canonical v2.0 wire format.
39
+ *
40
+ * When the legacy shape is detected a `console.warn` deprecation
41
+ * notice is emitted once per call-site process lifetime. The shim
42
+ * will be removed in v3.0.0.
43
+ */
44
+ declare function normalizeEvaluateRequest(input: LegacyEvaluateRequest | V2EvaluateRequest): V2EvaluateRequest;
45
+ /**
46
+ * Legacy v1.x evaluate response shape returned by older server
47
+ * deployments.
20
48
  */
21
- /** Policy decision enum used on `audit_events.decision`. */
22
- type AuditDecision = 'allow' | 'deny' | 'hold' | 'escalate';
49
+ interface LegacyEvaluateResponse {
50
+ permitted?: boolean;
51
+ decision_id?: string;
52
+ reason?: string;
53
+ audit_hash?: string;
54
+ timestamp?: string;
55
+ }
56
+ /** v2.0 evaluate response shape (canonical wire format). */
57
+ interface V2EvaluateResponse {
58
+ decision: 'allow' | 'deny' | 'hold' | 'escalate';
59
+ permit_token?: string;
60
+ request_id?: string;
61
+ expires_at?: string;
62
+ denial?: {
63
+ reason?: string;
64
+ code?: string;
65
+ };
66
+ }
23
67
  /**
24
- * Signing status reported on an export bundle. "signed" is the normal
25
- * path; "unsigned" means the deployment has no active signing key;
26
- * "signing_failed" means a key is configured but signing errored and
27
- * the export was returned anyway (the signature is an empty string).
68
+ * Normalise an evaluate response from either the legacy v1.x shape
69
+ * (`permitted` / `decision_id`) or the current v2.0 shape
70
+ * (`decision` / `permit_token`) into the canonical v2.0 wire format.
71
+ *
72
+ * Used internally by the client to tolerate older atlasent-api
73
+ * deployments without surfacing the impedance mismatch to callers.
28
74
  */
29
- type AuditExportSignatureStatus = 'signed' | 'unsigned' | 'signing_failed';
75
+ declare function normalizeEvaluateResponse(wire: LegacyEvaluateResponse | V2EvaluateResponse): V2EvaluateResponse;
76
+
30
77
  /**
31
- * One persisted row from `audit_events`, as returned by
32
- * `GET /v1/audit/events` and embedded inside `AuditExport.events`.
78
+ * Human-in-the-loop (HITL) types wire shape for `/v1/hitl/*`.
33
79
  *
34
- * `decision` is nullable because not every event is an evaluation —
35
- * CRUD-style audit writes (e.g. `policy.updated`) omit it. All other
36
- * nullable fields follow the same "field doesn't apply to this event
37
- * type" convention rather than "unknown value".
80
+ * Mirrors `supabase/functions/_shared/hitl-policy.ts` and the
81
+ * `hitl_escalations` row shape after migration 20260507060000.
82
+ * Treat as wire-types only: do not embed business logic that the
83
+ * server-side resolver owns (quorum math, status transitions).
38
84
  */
39
- interface AuditEvent {
40
- /** Event UUID. Stable; surfaces as `tampered_event_ids` on verify failure. */
85
+ type HitlQuorumTier = "single_approver" | "simple_majority" | "two_thirds" | "unanimous";
86
+ type HitlStatus = "pending" | "escalated" | "approved" | "rejected" | "auto_approved" | "timed_out";
87
+ type HitlFallbackDecision = "reject" | "approve";
88
+ interface HitlQuorumProgress {
89
+ required: number;
90
+ approved: number;
91
+ rejected: number;
92
+ remaining: number;
93
+ satisfied: boolean;
94
+ rejected_terminal: boolean;
95
+ }
96
+ interface HitlEscalation {
41
97
  id: string;
42
- /** Organization this event belongs to. */
43
98
  org_id: string;
44
- /** Per-org monotonic sequence. Used as the pagination cursor's payload. */
45
- sequence: number;
46
- /** Event type tag (e.g. "evaluate.allow", "policy.updated"). */
47
- type: string;
48
- /** Policy decision when the event is an evaluation; `null` otherwise. */
49
- decision: AuditDecision | null;
50
- /** Actor id (user / API key / agent) when applicable. */
99
+ agent_id: string;
100
+ sandbox_run_id: string | null;
101
+ status: HitlStatus;
102
+ escalation_reason: string;
103
+ proposed_action: Record<string, unknown> | null;
104
+ risk_score: number | null;
105
+ assigned_to_user_id: string | null;
106
+ assigned_to_role: string | null;
107
+ resolved_by: string | null;
108
+ resolution_note: string | null;
109
+ auto_approved_reason: string | null;
110
+ resolved_at: string | null;
111
+ timeout_at: string | null;
112
+ created_at: string;
113
+ quorum_required: HitlQuorumTier;
114
+ min_approvers: number;
115
+ approver_pool_size: number;
116
+ escalation_depth: number;
117
+ max_escalation_depth: number;
118
+ fallback_decision: HitlFallbackDecision;
119
+ governance_advisory_id: string | null;
120
+ expired_reason: "sla_expired" | "escalation_chain_exhausted" | "manual_expire" | null;
121
+ /**
122
+ * Arbitrary key/value metadata attached at creation time.
123
+ * `null` when none was provided.
124
+ */
125
+ metadata: Record<string, unknown> | null;
126
+ quorum_progress?: HitlQuorumProgress;
127
+ approver_pool?: HitlApproverPoolEntry[];
128
+ quorum_threshold?: number | null;
129
+ ai_unavailable_fallback?: HitlAiUnavailableFallback;
130
+ fallback_human_role?: string | null;
131
+ pool_unavailable_at?: string | null;
132
+ /** Populated when the server attaches a heterogeneous-quorum tally. */
133
+ heterogeneous_tally?: HitlHeterogeneousQuorumTally;
134
+ }
135
+ interface HitlApprovalRecord {
136
+ id: string;
137
+ user_id: string | null;
138
+ actor_label: string | null;
139
+ decision: "approve" | "reject";
140
+ note: string | null;
141
+ quorum_at_vote: HitlQuorumTier;
142
+ created_at: string;
143
+ /** Which kind of approver cast this vote (default `"human"`). */
144
+ approver_type?: HitlApproverType;
145
+ }
146
+ interface HitlChainHop {
147
+ id: string;
148
+ depth: number;
149
+ from_user_id: string | null;
150
+ from_role: string | null;
151
+ to_user_id: string | null;
152
+ to_role: string | null;
153
+ escalated_by: string | null;
154
+ reason: string | null;
155
+ created_at: string;
156
+ }
157
+ interface ListHitlEscalationsRequest {
158
+ status?: HitlStatus;
159
+ agentId?: string;
160
+ assignedToUserId?: string;
161
+ limit?: number;
162
+ cursor?: string;
163
+ }
164
+ interface ListHitlEscalationsResponse {
165
+ escalations: HitlEscalation[];
166
+ total: number;
167
+ next_cursor?: string;
168
+ }
169
+ /**
170
+ * Wire shape for `POST /v1/hitl` — open a new escalation.
171
+ *
172
+ * The agent-side bridge between a `hold` outcome from `protect()`
173
+ * and the approval queue. Only `agent_id` and `escalation_reason`
174
+ * are required; the rest map to defaults configured on the
175
+ * server-side policy. Pass `approver_pool` to use the heterogeneous
176
+ * N-of-M extension instead of the homogeneous quorum tier.
177
+ */
178
+ interface HitlCreateRequest {
179
+ agent_id: string;
180
+ escalation_reason: string;
181
+ sandbox_run_id?: string;
182
+ proposed_action?: Record<string, unknown>;
183
+ risk_score?: number;
184
+ assigned_to_user_id?: string;
185
+ assigned_to_role?: string;
186
+ quorum_required?: HitlQuorumTier;
187
+ min_approvers?: number;
188
+ approver_pool_size?: number;
189
+ max_escalation_depth?: number;
190
+ fallback_decision?: HitlFallbackDecision;
191
+ timeout_at?: string;
192
+ governance_advisory_id?: string;
193
+ approver_pool?: HitlApproverPoolEntry[];
194
+ quorum_threshold?: number;
195
+ ai_unavailable_fallback?: HitlAiUnavailableFallback;
196
+ fallback_human_role?: string;
197
+ /** Arbitrary key/value metadata to attach to the escalation record. */
198
+ metadata?: Record<string, unknown>;
199
+ }
200
+ interface HitlApproveRequest {
201
+ note?: string;
202
+ }
203
+ interface HitlRejectRequest {
204
+ note?: string;
205
+ }
206
+ interface HitlEscalateRequest {
207
+ to_role?: string;
208
+ to_user_id?: string;
209
+ reason?: string;
210
+ }
211
+ /**
212
+ * Wire shape for `POST /v1/escalations/:id/respond` — cast a vote on an
213
+ * existing escalation. Mirrors the `RespondBody` schema in
214
+ * atlasent-control-plane `api/src/routes/hitl.ts`.
215
+ */
216
+ interface HitlRespondRequest {
217
+ /** The approver's decision. */
218
+ decision: "approve" | "reject";
219
+ /** Optional human-readable note attached to the approval record. */
220
+ note?: string;
221
+ }
222
+ /**
223
+ * Translate a quorum tier and approver-pool size to the minimum
224
+ * number of `approve` votes required to resolve the escalation.
225
+ *
226
+ * Mirrors the canonical `requiredApproverCount()` in
227
+ * atlasent-api `_shared/hitl-policy.ts` and the SQL
228
+ * `public.hitl_required_approver_count()` helper. Provided here so
229
+ * SDK consumers can render a "you are the Nth of M approvers" hint
230
+ * without a server round-trip; the authoritative count still comes
231
+ * from the server's `quorum_progress` payload.
232
+ */
233
+ declare function hitlRequiredApproverCount(quorum: HitlQuorumTier, poolSize: number): number;
234
+ type HitlApproverType = "human" | "ai_supervisor" | "automated_compliance" | "hardware_signer" | "service_account";
235
+ type HitlAiUnavailableFallback = "escalate_to_human" | "reduce_pool" | "fail_closed";
236
+ interface HitlApproverPoolEntry {
237
+ type: HitlApproverType;
238
+ principal_id: string;
239
+ role?: string;
240
+ weight?: number;
241
+ required?: boolean;
242
+ /** Marker for slots inserted by the AI-unavailable fallback. */
243
+ origin?: string;
244
+ }
245
+ interface HitlHeterogeneousQuorumExtension {
246
+ approver_pool: HitlApproverPoolEntry[];
247
+ quorum_threshold: number | null;
248
+ ai_unavailable_fallback: HitlAiUnavailableFallback;
249
+ fallback_human_role: string | null;
250
+ pool_unavailable_at: string | null;
251
+ }
252
+ interface HitlHeterogeneousQuorumTally {
253
+ pool_size: number;
254
+ effective_pool_size: number;
255
+ required_threshold: number;
256
+ approve_count: number;
257
+ reject_count: number;
258
+ unavailable_count: number;
259
+ /** Per-approver-type breakdown: `{ ai_supervisor: { approve: 1, reject: 0 } }` */
260
+ by_type: Record<HitlApproverType, {
261
+ approve: number;
262
+ reject: number;
263
+ }>;
264
+ meets_threshold: boolean;
265
+ any_required_reject: boolean;
266
+ any_required_missing: boolean;
267
+ }
268
+ /**
269
+ * Detail response returned by `GET /v1/escalations/:id`.
270
+ *
271
+ * Mirrors `HitlDetailResponse` in atlasent-control-plane
272
+ * `api/src/schemas/hitl.ts`.
273
+ */
274
+ interface HitlDetailResponse {
275
+ escalation: HitlEscalation;
276
+ approval_records: HitlApprovalRecord[];
277
+ }
278
+ /**
279
+ * Paginated list response returned by `GET /v1/escalations`.
280
+ *
281
+ * Mirrors `HitlListResponse` in atlasent-control-plane
282
+ * `api/src/schemas/hitl.ts`.
283
+ */
284
+ interface HitlListResponse {
285
+ escalations: HitlEscalation[];
286
+ total: number;
287
+ next_cursor: string | null;
288
+ }
289
+
290
+ /**
291
+ * Governance graph types: named query results, graph node/edge shapes.
292
+ *
293
+ * Mirrors the `query_governance_graph()` SQL function dispatched by
294
+ * `GET /v1/governance/graph/query?type=<query_type>`.
295
+ */
296
+
297
+ /**
298
+ * Named traversal queries dispatched by `query_governance_graph()`.
299
+ *
300
+ * | Type | Returns |
301
+ * |---|---|
302
+ * | `production_deployers` | Actors with `executed_in → environment=production` edges |
303
+ * | `execution_approvers` | Actors as targets of `approved_by` edges |
304
+ * | `quorum_bypass_connectors` | Connector nodes with outbound `violates` edges |
305
+ * | `emergency_override_actions` | Execution nodes with `metadata.used_override = true` |
306
+ * | `connected_systems` | Connector/service/external-system nodes with `connected_to`/`synced_from` edges |
307
+ * | `user_approvals` | `approved_by` edges where target `external_id = params.actor_id` (requires `actor_id` param) |
308
+ */
309
+ type GovernanceGraphQueryType = "production_deployers" | "execution_approvers" | "quorum_bypass_connectors" | "emergency_override_actions" | "connected_systems" | "user_approvals";
310
+ /**
311
+ * Node type values from the `graph_node_type` DB enum.
312
+ * Additional values may be introduced server-side; treat as open.
313
+ */
314
+ type GraphNodeType = "execution" | "permit" | "incident" | "connector" | "service" | "external_system" | "actor" | "policy" | "environment" | (string & Record<never, never>);
315
+ /**
316
+ * Edge type values from the `graph_edge_type` DB enum.
317
+ * Additional values may be introduced server-side; treat as open.
318
+ */
319
+ type GraphEdgeType = "governed_by" | "incident_involves" | "synced_from" | "approved_by" | "executed_in" | "violates" | "connected_to" | (string & Record<never, never>);
320
+ /** Full graph node row returned by `GET /v1/governance/graph`. */
321
+ interface GraphNode {
322
+ id: string;
323
+ org_id: string;
324
+ node_type: GraphNodeType;
325
+ external_id: string | null;
326
+ metadata: Record<string, unknown>;
327
+ created_at: string;
328
+ updated_at: string;
329
+ }
330
+ /** Full graph edge row returned by `GET /v1/governance/graph/edges`. */
331
+ interface GraphEdge {
332
+ id: string;
333
+ org_id: string;
334
+ edge_type: GraphEdgeType;
335
+ source_node_id: string;
336
+ target_node_id: string;
337
+ metadata: Record<string, unknown>;
338
+ created_at: string;
339
+ }
340
+ /** Row returned by `query_type = "production_deployers"`. */
341
+ interface ProductionDeployerRow {
342
+ node_id: string;
343
+ actor_id: string | null;
344
+ exec_count: number;
345
+ last_seen: string | null;
346
+ }
347
+ /** Row returned by `query_type = "execution_approvers"`. */
348
+ interface ExecutionApproverRow {
349
+ node_id: string;
350
+ actor_id: string | null;
351
+ approval_count: number;
352
+ }
353
+ /** Row returned by `query_type = "quorum_bypass_connectors"`. */
354
+ interface QuorumBypassConnectorRow {
355
+ node_id: string;
356
+ connector_id: string | null;
357
+ violation_count: number;
358
+ }
359
+ /** Row returned by `query_type = "emergency_override_actions"`. */
360
+ interface EmergencyOverrideActionRow {
361
+ node_id: string;
362
+ execution_id: string | null;
363
+ actor_id: string | null;
364
+ timestamp: string | null;
365
+ }
366
+ /** Row returned by `query_type = "connected_systems"`. */
367
+ interface ConnectedSystemRow {
368
+ node_id: string;
369
+ system_id: string | null;
370
+ node_type: GraphNodeType;
371
+ edge_type: GraphEdgeType;
372
+ }
373
+ /** Row returned by `query_type = "user_approvals"`. */
374
+ interface UserApprovalRow {
375
+ edge_id: string;
376
+ source_node_id: string;
377
+ created_at: string;
378
+ }
379
+ /**
380
+ * Conditional type mapping each {@link GovernanceGraphQueryType} to its
381
+ * per-row result shape. Use as `GovernanceGraphResultRow<"production_deployers">`.
382
+ */
383
+ type GovernanceGraphResultRow<T extends GovernanceGraphQueryType = GovernanceGraphQueryType> = T extends "production_deployers" ? ProductionDeployerRow : T extends "execution_approvers" ? ExecutionApproverRow : T extends "quorum_bypass_connectors" ? QuorumBypassConnectorRow : T extends "emergency_override_actions" ? EmergencyOverrideActionRow : T extends "connected_systems" ? ConnectedSystemRow : T extends "user_approvals" ? UserApprovalRow : Record<string, unknown>;
384
+ /**
385
+ * Optional parameters for `queryGovernanceGraph()`.
386
+ *
387
+ * `actor_id` is required when `query_type = "user_approvals"`.
388
+ */
389
+ interface GovernanceGraphQueryParams {
390
+ actor_id?: string;
391
+ }
392
+ /** Response from {@link AtlaSentClient.queryGovernanceGraph}. */
393
+ interface GovernanceGraphQueryResponse<T extends GovernanceGraphQueryType = GovernanceGraphQueryType> {
394
+ query_type: T;
395
+ results: GovernanceGraphResultRow<T>[];
396
+ org_id: string;
397
+ rateLimit: RateLimitState | null;
398
+ }
399
+ /** Response from `listGraphNodes()`. */
400
+ interface ListGraphNodesResponse {
401
+ nodes: GraphNode[];
402
+ total: number;
403
+ nextCursor?: string;
404
+ rateLimit: RateLimitState | null;
405
+ }
406
+ /** Response from `listGraphEdges()`. */
407
+ interface ListGraphEdgesResponse {
408
+ edges: GraphEdge[];
409
+ total: number;
410
+ nextCursor?: string;
411
+ rateLimit: RateLimitState | null;
412
+ }
413
+ /** Input for `createGraphNode()`. */
414
+ interface CreateGraphNodeInput {
415
+ node_type: GraphNodeType;
416
+ external_id?: string;
417
+ metadata?: Record<string, unknown>;
418
+ }
419
+ /** Input for `createGraphEdge()`. */
420
+ interface CreateGraphEdgeInput {
421
+ edge_type: GraphEdgeType;
422
+ source_node_id: string;
423
+ target_node_id: string;
424
+ metadata?: Record<string, unknown>;
425
+ }
426
+
427
+ /**
428
+ * Incident reconstruction types: shapes returned by
429
+ * `reconstruct_incident_chains_v2()` via
430
+ * `GET /v1/governance/timeline/incident/{incidentId}`.
431
+ */
432
+
433
+ /**
434
+ * Single execution row returned by `reconstruct_incident_chains_v2()`.
435
+ *
436
+ * All §13.1 additive columns are nullable — rows inserted before the
437
+ * migration have `null` for any field added after their insert.
438
+ */
439
+ interface IncidentChainExecutionRow {
440
+ execution_id: string;
51
441
  actor_id: string | null;
52
- /** Optional resource tag — e.g. "policy". */
53
- resource_type: string | null;
54
- /** Optional resource id — paired with `resource_type`. */
442
+ action_id: string | null;
443
+ /** Broad action category (e.g. `"write"`, `"admin"`). */
444
+ action_class: string | null;
445
+ outcome: string | null;
446
+ started_at: string | null;
447
+ completed_at: string | null;
448
+ /** UUID of the delegation chain this execution belongs to. */
449
+ delegation_chain_id: string | null;
450
+ /** UUID of the original execution this is a replay of. */
451
+ replay_of_execution_id: string | null;
452
+ /** UUID of the incident this execution is linked to (§13.1 column). */
453
+ incident_id: string | null;
454
+ /** UUID of the policy version pinned at evaluate() time. */
455
+ policy_version_id: string | null;
456
+ /** UUID of the bundle version pinned at evaluate() time. */
457
+ bundle_version_id: string | null;
458
+ decision_id: string | null;
459
+ subject_id: string | null;
55
460
  resource_id: string | null;
56
- /** Canonical JSON of the event payload. Hashed into `hash`. */
57
- payload: Record<string, unknown> | null;
58
- /** SHA-256(prev_hash || canonicalJSON(payload)), hex. */
59
- hash: string;
60
- /** Previous event's `hash` (genesis is `"0".repeat(64)`). */
61
- previous_hash: string;
62
- /** When the underlying action occurred (ISO 8601). */
461
+ /** Structured deny/abort code (e.g. `"policy_deny"`, `"quorum_failed"`). */
462
+ outcome_reason: string | null;
463
+ parent_execution_id: string | null;
464
+ }
465
+ /** Per-actor summary within the reconstructed incident chain. */
466
+ interface IncidentChainActorEntry {
467
+ actor_id: string;
468
+ execution_ids: string[];
469
+ execution_count: number;
470
+ }
471
+ /** Evidence row bound to the incident chain (shape is open/forward-compat). */
472
+ type IncidentChainEvidenceRow = Record<string, unknown>;
473
+ /**
474
+ * Full response from `GET /v1/governance/timeline/incident/{incidentId}`.
475
+ *
476
+ * Backed by `reconstruct_incident_chains_v2()` which fixes the
477
+ * `executor_id → actor_id` bug that caused silent empty timelines
478
+ * in the v1 function.
479
+ */
480
+ interface IncidentTimelineResponse {
481
+ incident_id: string;
482
+ /** All execution rows in the incident, newest first. */
483
+ execution_rows: IncidentChainExecutionRow[];
484
+ /** Per-actor rollup: which executions each actor was responsible for. */
485
+ actor_timeline: IncidentChainActorEntry[];
486
+ /** Evidence rows bound to this incident's chain. */
487
+ evidence: IncidentChainEvidenceRow[];
488
+ rateLimit: RateLimitState | null;
489
+ }
490
+
491
+ /**
492
+ * Connector management types: connector lifecycle, credential security,
493
+ * enforcement policies, audit log, and sync state.
494
+ *
495
+ * Mirrors the `v1-connectors`, `v1-connector-enforcement` edge functions
496
+ * and associated DB tables (connector_credentials, connector_enforcement_policies,
497
+ * connector_audit_log, connector_sync_state).
498
+ */
499
+
500
+ /** Supported external connector types. */
501
+ type ConnectorType = "github" | "stripe" | "slack" | "salesforce" | "jira" | "okta" | "aws" | "gcp" | "azure" | "ci_cd" | "custom" | (string & Record<never, never>);
502
+ /** Connector lifecycle status. */
503
+ type ConnectorStatus = "pending_install" | "active" | "syncing" | "error" | "revoked";
504
+ /** Full connector row returned by `GET /v1/governance/connectors`. */
505
+ interface ConnectorRow {
506
+ id: string;
507
+ org_id: string;
508
+ connector_type: ConnectorType;
509
+ name: string;
510
+ environment: string;
511
+ status: ConnectorStatus;
512
+ scopes: string[];
513
+ config: Record<string, unknown>;
514
+ last_synced_at: string | null;
515
+ created_at: string;
516
+ updated_at: string;
517
+ }
518
+ /** Credential type stored in connector_credentials. */
519
+ type ConnectorCredentialType = "oauth_token" | "api_key" | "webhook_secret" | "service_account" | "mtls_cert";
520
+ /**
521
+ * Credential metadata row.
522
+ * `encrypted_value` is never returned in API responses — only metadata is exposed.
523
+ */
524
+ interface ConnectorCredentialRow {
525
+ id: string;
526
+ org_id: string;
527
+ connector_id: string;
528
+ credential_type: ConnectorCredentialType;
529
+ scope: string[];
530
+ expires_at: string | null;
531
+ rotated_at: string | null;
532
+ rotated_by: string | null;
533
+ revoked_at: string | null;
534
+ revoked_by: string | null;
535
+ revoke_reason: string | null;
536
+ version: number;
537
+ created_at: string;
538
+ updated_at: string;
539
+ }
540
+ /** Action a connector enforcement policy can require. */
541
+ type EnforcementAction = "require_permit" | "require_quorum" | "require_approval" | "block" | "audit_only";
542
+ /** Quorum configuration embedded in enforcement policies. */
543
+ interface EnforcementQuorumConfig {
544
+ min_approvers: number;
545
+ required_roles?: string[];
546
+ timeout_minutes?: number;
547
+ }
548
+ /** Single connector enforcement policy row. */
549
+ interface ConnectorEnforcementPolicy {
550
+ id: string;
551
+ org_id: string;
552
+ connector_type: ConnectorType;
553
+ /** Event type that triggers policy evaluation (e.g. `"push"`, `"deploy"`, `"merge"`). */
554
+ trigger_event: string;
555
+ /** Declarative condition evaluated against the event payload. */
556
+ condition: Record<string, unknown>;
557
+ required_action: EnforcementAction;
558
+ quorum_config: EnforcementQuorumConfig | null;
559
+ /** Environments this policy applies to (e.g. `["production"]`). Empty = all. */
560
+ environment_scope: string[];
561
+ enabled: boolean;
562
+ /** Higher priority policies are evaluated first. */
563
+ priority: number;
564
+ created_at: string;
565
+ updated_at: string;
566
+ }
567
+ /**
568
+ * Single append-only connector audit log entry from `connector_audit_log`.
569
+ * Entries are never updated or deleted — only inserted.
570
+ */
571
+ interface ConnectorAuditLogEntry {
572
+ id: string;
573
+ org_id: string;
574
+ connector_id: string;
575
+ actor_id: string | null;
576
+ operation: string;
577
+ /** `"success"` | `"failure"` | `"blocked"` */
578
+ outcome: string;
579
+ detail: Record<string, unknown>;
580
+ ip_address: string | null;
63
581
  occurred_at: string;
64
- /** When the row was persisted (ISO 8601). */
582
+ }
583
+ /** Sync state snapshot for a connector (one row per connector_id). */
584
+ interface ConnectorSyncState {
585
+ id: string;
586
+ org_id: string;
587
+ connector_id: string;
588
+ last_sync_at: string | null;
589
+ /** `"success"` | `"failure"` | `"running"` | `"skipped"` */
590
+ last_sync_status: string | null;
591
+ last_sync_error: string | null;
592
+ /** Opaque cursor passed to the next incremental sync. */
593
+ sync_cursor: Record<string, unknown> | null;
594
+ next_sync_at: string | null;
65
595
  created_at: string;
596
+ updated_at: string;
597
+ }
598
+ /** Input event for connector enforcement evaluation via `v1-connector-enforcement`. */
599
+ interface ConnectorEnforcementEventInput {
600
+ connector_id: string;
601
+ event_type: string;
602
+ actor_id?: string;
603
+ environment?: string;
604
+ payload?: Record<string, unknown>;
605
+ }
606
+ /** Result of a connector enforcement evaluation. */
607
+ interface ConnectorEnforcementResult {
608
+ /** Enforcement decision — fail-closed: defaults to `"block"` on evaluation error. */
609
+ decision: "permit" | "block" | "require_quorum" | "require_approval" | "audit_only";
610
+ policy_id: string | null;
611
+ reason: string;
612
+ audit_log_id: string | null;
613
+ rateLimit: RateLimitState | null;
614
+ }
615
+ /** Input for `installConnector()`. */
616
+ interface InstallConnectorInput {
617
+ connector_type: ConnectorType;
618
+ name: string;
619
+ environment: string;
620
+ scopes?: string[];
621
+ config?: Record<string, unknown>;
622
+ }
623
+ /** Input for `authenticateConnector()`. The `encrypted_value` must be pre-encrypted by the caller. */
624
+ interface AuthenticateConnectorInput {
625
+ credential_type: ConnectorCredentialType;
626
+ /** Pre-encrypted credential value. Never transmit plaintext. */
627
+ encrypted_value: string;
628
+ scope?: string[];
629
+ expires_at?: string;
630
+ }
631
+ /** Input for `upsertEnforcementPolicy()`. */
632
+ interface UpsertEnforcementPolicyInput {
633
+ connector_type: ConnectorType;
634
+ trigger_event: string;
635
+ condition?: Record<string, unknown>;
636
+ required_action: EnforcementAction;
637
+ quorum_config?: EnforcementQuorumConfig;
638
+ environment_scope?: string[];
639
+ enabled?: boolean;
640
+ priority?: number;
641
+ }
642
+ /** Response from `listConnectors()`. */
643
+ interface ListConnectorsResponse {
644
+ connectors: ConnectorRow[];
645
+ total: number;
646
+ nextCursor?: string;
647
+ rateLimit: RateLimitState | null;
648
+ }
649
+ /** Response from `installConnector()`. */
650
+ interface InstallConnectorResponse {
651
+ connector: ConnectorRow;
652
+ rateLimit: RateLimitState | null;
653
+ }
654
+ /** Response from `authenticateConnector()`. */
655
+ interface AuthenticateConnectorResponse {
656
+ credential_id: string;
657
+ version: number;
658
+ rateLimit: RateLimitState | null;
659
+ }
660
+ /** Response from `syncConnector()`. */
661
+ interface SyncConnectorResponse {
662
+ connector_id: string;
663
+ status: ConnectorStatus;
664
+ sync_started_at: string;
665
+ rateLimit: RateLimitState | null;
666
+ }
667
+ /** Response from `revokeConnector()`. */
668
+ interface RevokeConnectorResponse {
669
+ connector_id: string;
670
+ revoked_at: string;
671
+ rateLimit: RateLimitState | null;
66
672
  }
673
+ /** Response from `rotateConnectorCredentials()`. */
674
+ interface RotateCredentialsResponse {
675
+ connector_id: string;
676
+ new_version: number;
677
+ rotated_at: string;
678
+ rateLimit: RateLimitState | null;
679
+ }
680
+ /** Response from `listEnforcementPolicies()`. */
681
+ interface ListEnforcementPoliciesResponse {
682
+ policies: ConnectorEnforcementPolicy[];
683
+ total: number;
684
+ rateLimit: RateLimitState | null;
685
+ }
686
+ /** Response from `upsertEnforcementPolicy()`. */
687
+ interface UpsertEnforcementPolicyResponse {
688
+ policy: ConnectorEnforcementPolicy;
689
+ rateLimit: RateLimitState | null;
690
+ }
691
+
67
692
  /**
68
- * Response shape for `GET /v1/audit/events`.
693
+ * Organizational risk graph types: 5-dimension risk scoring and
694
+ * recompute trigger shapes.
69
695
  *
70
- * `total` is the filter's full count (not just this page) so callers
71
- * can show "page 1 of N" without an extra HEAD request.
696
+ * Mirrors `v1-risk-graph` (compute_org_risk / get_latest_org_risk ops)
697
+ * and the `organizational_risk_scores` DB table.
698
+ */
699
+
700
+ /**
701
+ * Bucketed risk level derived from `overall_score`.
702
+ *
703
+ * | Level | Score range |
704
+ * |---|---|
705
+ * | `"low"` | 0–30 |
706
+ * | `"medium"` | 31–60 |
707
+ * | `"high"` | 61–85 |
708
+ * | `"critical"` | 86–100 |
709
+ */
710
+ type OrgRiskLevel = "low" | "medium" | "high" | "critical";
711
+ /**
712
+ * Full organizational risk score from `organizational_risk_scores`.
72
713
  *
73
- * `next_cursor` is an opaque base64url string. Pass it back verbatim
74
- * as `?cursor=...` to fetch the next page. Absent when this is the
75
- * last page.
714
+ * All sub-scores are 0–100 (higher = more risk). `overall_score` is a
715
+ * weighted composite of the five dimensions; weights are internal and
716
+ * may change between releases without a breaking-change notice.
717
+ */
718
+ interface OrgRiskScore {
719
+ id: string;
720
+ org_id: string;
721
+ /** Composite risk score 0–100. */
722
+ overall_score: number;
723
+ risk_level: OrgRiskLevel;
724
+ /** Actor-level risk: recent overrides, blocked actions by specific actors. */
725
+ actor_risk_score: number;
726
+ /** Connector-level risk: revoked/errored connectors, failed sync cycles. */
727
+ connector_risk_score: number;
728
+ /** Gap between what enforcement policies require and what connectors actually enforce. */
729
+ enforcement_gap_score: number;
730
+ /** Normalized frequency of incidents within the scoring window. */
731
+ incident_frequency_score: number;
732
+ /** Rate of permits that were overridden relative to total permits issued. */
733
+ override_rate_score: number;
734
+ /** Actor IDs flagged as high-risk within the window. */
735
+ risky_actors: string[];
736
+ /** Connector IDs flagged as high-risk within the window. */
737
+ risky_systems: string[];
738
+ /** Execution IDs with repeated overrides in the window. */
739
+ repeated_overrides: string[];
740
+ /** Days of activity included in this score computation. */
741
+ window_days: number;
742
+ computed_at: string;
743
+ created_at: string;
744
+ }
745
+ /** Options for triggering an org risk recompute. */
746
+ interface ComputeOrgRiskOptions {
747
+ /** Activity window in days (server default: 30). */
748
+ window_days?: number;
749
+ }
750
+ /** Response from `computeOrgRisk()`. */
751
+ interface ComputeOrgRiskResponse {
752
+ score: OrgRiskScore;
753
+ rateLimit: RateLimitState | null;
754
+ }
755
+ /**
756
+ * Response from `getLatestOrgRisk()`.
757
+ * `score` is `null` if no risk computation has been run yet for the org.
76
758
  */
77
- interface AuditEventsPage {
78
- events: AuditEvent[];
759
+ interface GetLatestOrgRiskResponse {
760
+ score: OrgRiskScore | null;
761
+ rateLimit: RateLimitState | null;
762
+ }
763
+ /** Response from `listOrgRiskHistory()`. */
764
+ interface ListOrgRiskHistoryResponse {
765
+ scores: OrgRiskScore[];
79
766
  total: number;
80
- next_cursor?: string;
767
+ nextCursor?: string;
768
+ rateLimit: RateLimitState | null;
81
769
  }
770
+
82
771
  /**
83
- * Query parameters accepted by `GET /v1/audit/events`. Serialize as
84
- * URL search params — `types` is a comma-joined list on the wire
85
- * (e.g. `types=evaluate.allow,policy.updated`).
772
+ * Cross-Org Permission Negotiation.
86
773
  *
87
- * All fields are optional; the server defaults `limit` to 50 and caps
88
- * it at 500.
774
+ * Evaluates whether an identity in one organization is permitted to
775
+ * perform an action on resources owned by another organization.
776
+ * Resolves trust paths, conditions, and cross-org trust levels.
777
+ *
778
+ * Wire-stable as `cross_org_permission.v1`.
89
779
  */
90
- interface AuditEventsQuery {
91
- /** Comma-joined list of event types to filter on. */
92
- types?: string;
93
- /** Filter to a single actor. */
94
- actor_id?: string;
95
- /** Inclusive lower bound on `occurred_at` (ISO 8601). */
96
- from?: string;
97
- /** Inclusive upper bound on `occurred_at` (ISO 8601). */
98
- to?: string;
99
- /** Page size. Default 50, min 1, max 500. */
780
+ /** A single hop in the cross-org trust path. */
781
+ interface CrossOrgTrustHop {
782
+ org_id: string;
783
+ trust_type: string;
784
+ trust_level: string;
785
+ }
786
+ /** Request payload for a cross-org permission check. */
787
+ interface CrossOrgPermissionCheckRequest {
788
+ source_org_id: string;
789
+ target_org_id: string;
790
+ identity_id?: string;
791
+ action: string;
792
+ resource_type?: string;
793
+ resource_id?: string;
794
+ }
795
+ /** Result of a cross-org permission evaluation. */
796
+ interface CrossOrgPermissionCheckResult {
797
+ check_id: string;
798
+ allowed: boolean;
799
+ reason: string;
800
+ trust_path: Array<CrossOrgTrustHop>;
801
+ conditions: string[];
802
+ checked_at: string;
803
+ }
804
+ /** Parameters for listing previous cross-org permission checks. */
805
+ interface CrossOrgPermissionCheckListParams {
806
+ source_org_id?: string;
807
+ target_org_id?: string;
808
+ allowed?: boolean;
100
809
  limit?: number;
101
- /** Opaque cursor returned as `next_cursor` by the prior page. */
102
- cursor?: string;
103
810
  }
104
811
  /**
105
- * Response shape for `POST /v1/audit/exports` a signed bundle of
106
- * audit events suitable for offline verification.
812
+ * Summarize whether a cross-org check result is unconditionally allowed,
813
+ * conditionally allowed, or denied.
814
+ */
815
+ declare function summarizeCrossOrgPermission(result: CrossOrgPermissionCheckResult): "allowed" | "conditional" | "denied";
816
+
817
+ /**
818
+ * Anomaly Response Automation.
107
819
  *
108
- * `signature` is detached Ed25519 over `signedBytesFor(bundle)` (see
109
- * `./auditBundle.ts`). An empty string means the server attempted to
110
- * sign but failed; check `signature_status` to distinguish.
820
+ * Rules-driven automated responses to governance anomalies detected
821
+ * during agent execution. Supports freezing agents, creating incidents,
822
+ * notifying administrators, requiring human-in-the-loop review,
823
+ * rolling back executions, and escalating to regulators.
111
824
  *
112
- * `tampered_event_ids` surfaces rows whose recomputed hash doesn't
113
- * match the stored hash — even when `chain_integrity_ok` is false,
114
- * the signature still covers whatever the server emitted, so callers
115
- * that trust the signature must still inspect this list.
825
+ * Wire-stable as `anomaly_response.v1`.
116
826
  */
117
- interface AuditExport {
118
- /** Server-assigned UUID for this export. */
119
- export_id: string;
120
- /** Organization the bundle belongs to. */
827
+ /** The automated action type to take when an anomaly rule triggers. */
828
+ type AnomalyActionType = "freeze_agent" | "create_incident" | "notify_admin" | "require_hitl" | "rollback_execution" | "escalate_to_regulator";
829
+ /** A rule that triggers an automated response when an anomaly threshold is crossed. */
830
+ interface AnomalyResponseRule {
831
+ id: string;
121
832
  org_id: string;
122
- /** Events in canonical (ascending sequence) order. */
123
- events: AuditEvent[];
124
- /** Last event's `hash`, or `"0".repeat(64)` if `events` is empty. */
125
- chain_head_hash: string;
126
- /** `true` iff adjacency + re-hash succeeded for every event. */
127
- chain_integrity_ok: boolean;
128
- /** `AuditEvent.id`s whose recomputed hash != stored hash. */
129
- tampered_event_ids: string[];
130
- /** Detached Ed25519 signature (base64url). Empty string on sign failure. */
131
- signature: string;
132
- /** Outcome of the signing attempt. */
133
- signature_status: AuditExportSignatureStatus;
134
- /** Registry id of the key that signed — absent when unsigned. */
135
- signing_key_id?: string;
136
- /** When the bundle was signed (ISO 8601). */
137
- signed_at: string;
833
+ name: string;
834
+ description?: string;
835
+ anomaly_score_threshold: number;
836
+ action_type: AnomalyActionType;
837
+ action_config: Record<string, unknown>;
838
+ is_active: boolean;
839
+ created_at: string;
840
+ updated_at: string;
841
+ }
842
+ /** A record of an anomaly response that was triggered. */
843
+ interface AnomalyResponseEvent {
844
+ id: string;
845
+ rule_id: string;
846
+ execution_id: string;
847
+ org_id: string;
848
+ anomaly_score: number;
849
+ action_type: AnomalyActionType;
850
+ action_result: Record<string, unknown>;
851
+ triggered_at: string;
852
+ }
853
+ /** Request body for creating a new anomaly response rule. */
854
+ interface CreateAnomalyResponseRuleRequest {
855
+ name: string;
856
+ description?: string;
857
+ anomaly_score_threshold: number;
858
+ action_type: AnomalyActionType;
859
+ action_config?: Record<string, unknown>;
860
+ }
861
+ /** Request body for manually triggering an anomaly response check. */
862
+ interface TriggerAnomalyResponseRequest {
863
+ execution_id: string;
864
+ anomaly_score: number;
865
+ context?: Record<string, unknown>;
866
+ }
867
+ /**
868
+ * Determine which rules from a set would trigger for a given anomaly score.
869
+ * Returns only active rules whose threshold is met or exceeded.
870
+ */
871
+ declare function matchAnomalyRules(rules: readonly AnomalyResponseRule[], anomalyScore: number): AnomalyResponseRule[];
872
+ /**
873
+ * Determine the most severe action type from a set of triggered rules.
874
+ * Severity order (highest first):
875
+ * escalate_to_regulator > rollback_execution > freeze_agent >
876
+ * require_hitl > create_incident > notify_admin
877
+ */
878
+ declare function highestSeverityAction(rules: readonly AnomalyResponseRule[]): AnomalyActionType | null;
879
+
880
+ /**
881
+ * Budget Exception Workflows.
882
+ *
883
+ * Structured request-and-approval process for temporary exceptions
884
+ * to budget policy limits. Supports creation, review, approval,
885
+ * rejection, and cancellation lifecycles with full audit trails.
886
+ *
887
+ * Wire-stable as `budget_exceptions.v1`.
888
+ */
889
+ /** Lifecycle status of a budget exception request. */
890
+ type BudgetExceptionStatus = "pending" | "under_review" | "approved" | "rejected" | "expired" | "cancelled";
891
+ /** A formal request for a temporary exception to a budget policy limit. */
892
+ interface BudgetExceptionRequest {
893
+ id: string;
894
+ org_id: string;
895
+ budget_policy_id?: string;
896
+ requested_by: string;
897
+ amount_requested: number;
898
+ currency: string;
899
+ reason: string;
900
+ justification?: string;
901
+ business_impact?: string;
902
+ status: BudgetExceptionStatus;
903
+ reviewed_by?: string;
904
+ reviewed_at?: string;
905
+ review_notes?: string;
906
+ effective_from?: string;
907
+ effective_until?: string;
908
+ approved_amount?: number;
909
+ conditions: string[];
910
+ created_at: string;
911
+ updated_at: string;
912
+ }
913
+ /** Request body for creating a new budget exception request. */
914
+ interface CreateBudgetExceptionRequest {
915
+ budget_policy_id?: string;
916
+ amount_requested: number;
917
+ currency?: string;
918
+ reason: string;
919
+ justification?: string;
920
+ business_impact?: string;
921
+ effective_from?: string;
922
+ effective_until?: string;
923
+ }
924
+ /** Request body for approving a budget exception. */
925
+ interface ApproveBudgetExceptionRequest {
926
+ review_notes?: string;
927
+ approved_amount: number;
928
+ conditions?: string[];
929
+ effective_from?: string;
930
+ effective_until?: string;
931
+ }
932
+ /**
933
+ * Returns true when an approved exception is currently in effect.
934
+ * An exception is in effect when:
935
+ * - status is "approved"
936
+ * - current time is within [effective_from, effective_until]
937
+ */
938
+ declare function isBudgetExceptionActive(exception: BudgetExceptionRequest, now?: Date): boolean;
939
+ /**
940
+ * Returns true when a budget exception request is in a terminal state
941
+ * (no further transitions are possible).
942
+ */
943
+ declare function isBudgetExceptionTerminal(status: BudgetExceptionStatus): boolean;
944
+
945
+ /**
946
+ * Regulatory Escalation Chain.
947
+ *
948
+ * Hierarchical escalation infrastructure for routing governance issues
949
+ * through defined authority levels. Supports multi-jurisdiction
950
+ * regulatory chains with SLA tracking and resolution workflows.
951
+ *
952
+ * Wire-stable as `regulatory_escalation.v1`.
953
+ */
954
+ /**
955
+ * A defined level in the regulatory authority hierarchy.
956
+ * Levels are ordered numerically — lower numbers = lower authority.
957
+ */
958
+ interface RegulatoryAuthorityLevel {
959
+ id: string;
960
+ org_id: string;
961
+ name: string;
962
+ level: number;
963
+ description?: string;
964
+ parent_level_id?: string;
965
+ jurisdiction?: string;
966
+ escalation_sla_hours: number;
967
+ created_at: string;
968
+ }
969
+ /** Lifecycle status of a regulatory escalation. */
970
+ type RegulatoryEscalationStatus = "pending" | "acknowledged" | "under_review" | "resolved" | "overridden";
971
+ /** A formal escalation between two regulatory authority levels. */
972
+ interface RegulatoryEscalation {
973
+ id: string;
974
+ org_id: string;
975
+ from_level_id: string;
976
+ to_level_id: string;
977
+ subject_type: string;
978
+ subject_id: string;
979
+ reason: string;
980
+ details: Record<string, unknown>;
981
+ status: RegulatoryEscalationStatus;
982
+ escalated_by: string;
983
+ acknowledged_by?: string;
984
+ acknowledged_at?: string;
985
+ resolved_by?: string;
986
+ resolved_at?: string;
987
+ resolution?: string;
988
+ resolution_details?: Record<string, unknown>;
989
+ created_at: string;
990
+ updated_at: string;
991
+ }
992
+ /** Request body for creating a new regulatory escalation. */
993
+ interface CreateRegulatoryEscalationRequest {
994
+ from_level_id: string;
995
+ to_level_id: string;
996
+ subject_type: string;
997
+ subject_id: string;
998
+ reason: string;
999
+ details?: Record<string, unknown>;
1000
+ }
1001
+ /**
1002
+ * Returns true when a regulatory escalation is in a terminal state.
1003
+ */
1004
+ declare function isRegulatoryEscalationTerminal(status: RegulatoryEscalationStatus): boolean;
1005
+ /**
1006
+ * Determine whether an escalation has breached its SLA.
1007
+ * Compares the SLA hours on the target authority level against the
1008
+ * elapsed time since creation.
1009
+ */
1010
+ declare function isEscalationSlaBreached(escalation: RegulatoryEscalation, targetLevel: RegulatoryAuthorityLevel, now?: Date): boolean;
1011
+
1012
+ /**
1013
+ * Incentive Signal Feedback Loop.
1014
+ *
1015
+ * Captures how governance actors respond to incentive alignment signals
1016
+ * and tracks outcomes. Feeds back into signal calibration and governance
1017
+ * health scoring over time.
1018
+ *
1019
+ * Wire-stable as `incentive_signal_feedback.v1`.
1020
+ */
1021
+ /** The type of action taken in response to a governance signal. */
1022
+ type SignalActionType = "accepted" | "dismissed" | "escalated" | "delegated" | "policy_updated" | "training_initiated" | "process_changed" | "monitoring_increased" | "auto_remediated";
1023
+ /** A record of an action taken in response to a governance signal. */
1024
+ interface GovernanceSignalAction {
1025
+ id: string;
1026
+ signal_id: string;
1027
+ org_id: string;
1028
+ action_type: SignalActionType;
1029
+ action_description?: string;
1030
+ taken_by?: string;
1031
+ taken_at: string;
1032
+ outcome_score?: number;
1033
+ outcome_description?: string;
1034
+ outcome_recorded_at?: string;
1035
+ metadata: Record<string, unknown>;
1036
+ }
1037
+ /** Request body for recording a new signal action. */
1038
+ interface RecordSignalActionRequest {
1039
+ action_type: SignalActionType;
1040
+ action_description?: string;
1041
+ metadata?: Record<string, unknown>;
1042
+ }
1043
+ /** Request body for recording an outcome on a previous signal action. */
1044
+ interface RecordSignalOutcomeRequest {
1045
+ outcome_score: number;
1046
+ outcome_description?: string;
1047
+ }
1048
+ /** Aggregate summary of signal actions for an organization. */
1049
+ interface SignalActionSummary {
1050
+ total_signals: number;
1051
+ acted_on: number;
1052
+ dismissed: number;
1053
+ average_outcome_score: number;
1054
+ by_action_type: Record<SignalActionType, {
1055
+ count: number;
1056
+ avg_outcome: number;
1057
+ }>;
1058
+ }
1059
+ /**
1060
+ * Compute a simple engagement rate from a signal action summary.
1061
+ * Returns the fraction of signals that received a non-dismissed response.
1062
+ */
1063
+ declare function computeSignalEngagementRate(summary: SignalActionSummary): number;
1064
+ /**
1065
+ * Determine whether a signal action represents a substantive governance
1066
+ * response (i.e. more than a dismissal or auto-remediation).
1067
+ */
1068
+ declare function isSubstantiveSignalResponse(actionType: SignalActionType): boolean;
1069
+
1070
+ /**
1071
+ * Cross-Org Impersonation.
1072
+ *
1073
+ * Allows a service account in one organization to impersonate a role in
1074
+ * another organization under explicit, audited grants. Supports bounded
1075
+ * token issuance, grant revocation, and token validation.
1076
+ *
1077
+ * Wire-stable as `cross_org_impersonation.v1`.
1078
+ */
1079
+ /** An explicit grant allowing one org's service account to impersonate a role in another org. */
1080
+ interface CrossOrgImpersonationGrant {
1081
+ id: string;
1082
+ grantor_org_id: string;
1083
+ grantee_org_id: string;
1084
+ grantee_service_account_id: string;
1085
+ impersonated_role: string;
1086
+ allowed_actions: string[];
1087
+ allowed_resource_types: string[];
1088
+ max_token_duration_seconds: number;
1089
+ is_active: boolean;
1090
+ created_by: string;
1091
+ created_at: string;
1092
+ expires_at?: string;
1093
+ revoked_at?: string;
1094
+ }
1095
+ /** Request body for creating a new impersonation grant. */
1096
+ interface CreateImpersonationGrantRequest {
1097
+ grantee_org_id: string;
1098
+ grantee_service_account_id: string;
1099
+ impersonated_role: string;
1100
+ allowed_actions: string[];
1101
+ allowed_resource_types: string[];
1102
+ max_token_duration_seconds?: number;
1103
+ expires_at?: string;
1104
+ }
1105
+ /** A short-lived impersonation token issued under a grant. */
1106
+ interface ImpersonationToken {
1107
+ token: string;
1108
+ expires_at: string;
1109
+ grant_id: string;
1110
+ }
1111
+ /** Result of validating an impersonation token. */
1112
+ interface ImpersonationValidationResult {
1113
+ valid: boolean;
1114
+ grant?: CrossOrgImpersonationGrant;
1115
+ impersonated_role?: string;
1116
+ allowed_actions?: string[];
1117
+ allowed_resource_types?: string[];
1118
+ error?: string;
1119
+ }
1120
+ /**
1121
+ * Returns true when an impersonation grant is currently usable:
1122
+ * - is_active is true
1123
+ * - not yet expired
1124
+ * - not revoked
1125
+ */
1126
+ declare function isImpersonationGrantUsable(grant: CrossOrgImpersonationGrant, now?: Date): boolean;
1127
+ /**
1128
+ * Clamp a requested token duration to the grant's maximum.
1129
+ * Returns the minimum of the requested duration and the grant ceiling.
1130
+ */
1131
+ declare function clampTokenDuration(grant: CrossOrgImpersonationGrant, requestedSeconds: number): number;
1132
+
1133
+ /**
1134
+ * AtlaSent HTTP client.
1135
+ *
1136
+ * Two public methods, both backed by native `fetch`:
1137
+ * - {@link AtlaSentClient.evaluate} → POST {baseUrl}/v1-evaluate
1138
+ * - {@link AtlaSentClient.verifyPermit} → POST {baseUrl}/v1-verify-permit
1139
+ *
1140
+ * Fail-closed: a clean policy DENY is returned (not thrown), but
1141
+ * network, timeout, bad response, 4xx/5xx, and rate-limit conditions
1142
+ * all throw {@link AtlaSentError}.
1143
+ */
1144
+
1145
+ declare class AtlaSentClient {
1146
+ private readonly apiKey;
1147
+ private readonly baseUrl;
1148
+ private readonly timeoutMs;
1149
+ private readonly fetchImpl;
1150
+ private readonly userAgent;
1151
+ private readonly retryPolicy;
1152
+ constructor(options: AtlaSentClientOptions);
1153
+ /**
1154
+ * Ask the policy engine whether an agent action is permitted.
1155
+ *
1156
+ * Accepts either the current v2.0 shape (`action_type` / `actor_id`)
1157
+ * or the legacy v1.x shape (`action` / `agent`). Legacy callers
1158
+ * receive a deprecation warning via `console.warn`; the shim is
1159
+ * handled by {@link normalizeEvaluateRequest} and will be removed
1160
+ * in v3.0.0.
1161
+ *
1162
+ * A "deny" is **not** thrown — it is returned in
1163
+ * `response.decision`. Network errors, invalid API key, rate
1164
+ * limits, timeouts, and malformed responses throw
1165
+ * {@link AtlaSentError}.
1166
+ */
1167
+ evaluate(input: EvaluateRequest | LegacyEvaluateRequest): Promise<EvaluateResponse>;
1168
+ /**
1169
+ * Pre-flight evaluation that always returns the constraint trace.
1170
+ *
1171
+ * Wraps `POST /v1-evaluate?include=constraint_trace`. Use this from
1172
+ * a workflow's submission step to surface trivial defects (missing
1173
+ * fields, wrong roles, mis-set context) BEFORE pushing the request
1174
+ * onto an approval queue — only requests that would actually pass
1175
+ * make it through to a human reviewer.
1176
+ *
1177
+ * Returns an {@link EvaluatePreflightResponse} carrying the regular
1178
+ * {@link EvaluateResponse} plus the {@link ConstraintTrace}. Unlike
1179
+ * {@link evaluate}, this method does NOT mark a non-allow as a
1180
+ * thrown condition — the whole point is to inspect both the outcome
1181
+ * AND the per-policy trace, so the caller branches on
1182
+ * `result.evaluation.decision` and reads `result.constraintTrace`
1183
+ * to render the failing stages.
1184
+ *
1185
+ * The constraint-trace shape mirrors `ConstraintTraceResponse` in
1186
+ * atlasent-api (`packages/types/src/index.ts`). On older
1187
+ * atlasent-api deployments that omit the trace, `constraintTrace`
1188
+ * is `null` rather than throwing — forward-compatible degradation.
1189
+ *
1190
+ * Performance: one extra round-trip on submission. Latency is
1191
+ * comparable to {@link evaluate}; the response body is fuller
1192
+ * (includes the per-stage trace) so the wire payload is larger.
1193
+ * If the caller does not need the trace, prefer {@link evaluate}.
1194
+ */
1195
+ evaluatePreflight(input: EvaluateRequest): Promise<EvaluatePreflightResponse>;
1196
+ /**
1197
+ * Verify that a previously issued permit is still valid.
1198
+ *
1199
+ * @deprecated Use {@link verifyPermitById} — the canonical REST
1200
+ * surface (`POST /v1/permits/{id}/verify`) returns the unified
1201
+ * verification envelope plus the full {@link PermitRecord}, instead
1202
+ * of the legacy `{verified, outcome, permitHash}` shape this method
1203
+ * emits. Will be removed in `@atlasent/sdk@3`.
1204
+ *
1205
+ * A `verified: false` response is **not** thrown — inspect the
1206
+ * returned object. Only transport / server errors throw.
1207
+ */
1208
+ verifyPermit(input: VerifyPermitRequest): Promise<VerifyPermitResponse>;
1209
+ /**
1210
+ * Run the canonical Deploy Gate V1 flow:
1211
+ * evaluate `production.deploy`, verify the issued permit server-side,
1212
+ * and return allow/block plus audit/evidence metadata.
1213
+ *
1214
+ * This helper never treats a signed/offline permit artifact as sufficient
1215
+ * authorization. Execution is allowed only when `POST /v1-evaluate` returns
1216
+ * `decision: "allow"` with a permit AND `POST /v1-verify-permit` returns
1217
+ * `verified: true` / `valid: true`.
1218
+ */
1219
+ deployGate(input?: DeployGateRequest): Promise<DeployGateResponse>;
1220
+ /**
1221
+ * Revoke a previously-issued permit so it can no longer pass
1222
+ * {@link verifyPermit}.
1223
+ *
1224
+ * @deprecated Use {@link revokePermitById} — the canonical REST
1225
+ * surface (`POST /v1/permits/{id}/revoke`) returns the full updated
1226
+ * {@link PermitRecord} with `revoked_at`/`revoked_by`/`revoke_reason`
1227
+ * populated, instead of the legacy `{revoked, permitId}` envelope
1228
+ * this method emits. Will be removed in `@atlasent/sdk@3`.
1229
+ *
1230
+ * Use this when an agent's action is cancelled, superseded, or
1231
+ * determined to be unauthorized after the fact. The revocation is
1232
+ * recorded in the audit log with the optional `reason`.
1233
+ *
1234
+ * Throws {@link AtlaSentError} on transport / auth failures.
1235
+ */
1236
+ revokePermit(input: RevokePermitRequest): Promise<RevokePermitResponse>;
1237
+ /**
1238
+ * Revoke a permit through the canonical REST surface
1239
+ * (`POST /v1/permits/{permitId}/revoke`).
1240
+ *
1241
+ * Returns the full updated {@link PermitRecord} with `status === 'revoked'`
1242
+ * and `revoked_at` / `revoked_by` / `revoke_reason` populated. After
1243
+ * revocation, subsequent verify calls return `410 PERMIT_REVOKED`.
1244
+ *
1245
+ * Idempotent on `409 permit_revoked` for already-revoked permits;
1246
+ * server returns the existing revoked row in that case.
1247
+ *
1248
+ * Throws {@link AtlaSentError} on `404` (permit not in calling org),
1249
+ * `409` (already in a terminal state), `410` (expired before revoke),
1250
+ * or `429` (rate limited).
1251
+ */
1252
+ revokePermitById(permitId: string, input?: RevokePermitByIdInput): Promise<RevokePermitByIdResponse>;
1253
+ /**
1254
+ * Verify a permit through the canonical REST surface
1255
+ * (`POST /v1/permits/{permitId}/verify`).
1256
+ *
1257
+ * Returns the unified verification envelope (`valid`,
1258
+ * `verification_type: 'permit'`, `reason`, `verified_at`, `evidence`)
1259
+ * plus the full {@link PermitRecord} fields preserved at the top
1260
+ * level. The `valid` field is the contract — pin to it.
1261
+ *
1262
+ * A `valid: false` is **not** thrown when the server returns 200 with
1263
+ * a denial reason (matches the verify-shape unification on the wire);
1264
+ * it is thrown on 4xx (`404` not found, `410` expired/consumed).
1265
+ */
1266
+ verifyPermitById(permitId: string): Promise<VerifyPermitByIdResponse>;
1267
+ /**
1268
+ * Get a single permit's full lifecycle state.
1269
+ *
1270
+ * Calls `GET /v1/permits/{permitId}` (the canonical REST surface).
1271
+ * Returns `status`, all timestamps, `revoked_at` / `revoked_by` /
1272
+ * `revoke_reason` (when applicable), and the bound `payload_hash`
1273
+ * / `decision_id`.
1274
+ *
1275
+ * Operator-facing introspection — answers "what state is this permit
1276
+ * in, and why?" without reading audit logs.
1277
+ *
1278
+ * Throws {@link AtlaSentError} on `404` (permit not in calling org)
1279
+ * or `410` (expired before retrieval).
1280
+ */
1281
+ getPermit(permitId: string): Promise<GetPermitResponse>;
1282
+ /**
1283
+ * Poll whether a permit is currently valid.
1284
+ *
1285
+ * Calls `GET /v1/permits/{permitId}/valid` — a lightweight read
1286
+ * returning only the status snapshot optimised for guard heartbeat
1287
+ * polling. Guards with `permitRevalidationIntervalMs` set race this
1288
+ * against `tool.execute()` and throw {@link PermitRevoked} when
1289
+ * `status === "revoked"` arrives.
1290
+ *
1291
+ * Throws {@link AtlaSentError} on transport / auth failures.
1292
+ */
1293
+ checkPermitValid(permitId: string): Promise<PermitValidResponse>;
1294
+ /**
1295
+ * List permits issued to the calling org, most-recently-issued first.
1296
+ *
1297
+ * Calls `GET /v1/permits` (the canonical REST surface). Cursor-paged.
1298
+ * Filters narrow on server side; pagination uses the `created_at`
1299
+ * timestamp opaquely (`nextCursor`).
1300
+ *
1301
+ * Designed for incident review, debugging, and compliance
1302
+ * reconstruction.
1303
+ */
1304
+ listPermits(input?: ListPermitsRequest): Promise<ListPermitsResponse>;
1305
+ /**
1306
+ * Self-introspection: ask the server to describe the API key this
1307
+ * client was constructed with. Returns the key's ID, organization,
1308
+ * environment, scopes, IP allowlist, per-minute rate limit, the
1309
+ * client IP the server observed, and the expiry (if any).
1310
+ *
1311
+ * Never includes the raw key or its hash. Safe to surface in operator
1312
+ * dashboards. Useful for `IP_NOT_ALLOWED` debugging (the server tells
1313
+ * you exactly which IP it saw) and for proactive expiry warnings.
1314
+ *
1315
+ * Throws {@link AtlaSentError} on transport / auth failures — same
1316
+ * taxonomy as {@link AtlaSentClient.evaluate}.
1317
+ */
1318
+ keySelf(): Promise<ApiKeySelfResponse>;
1319
+ /**
1320
+ * List persisted audit events for the authenticated organization
1321
+ * (`GET /v1-audit/events`). Returned rows are wire-identical with
1322
+ * the server: snake_case field names, including `previous_hash` and
1323
+ * the `hash` chain, so the response can be fed straight into the
1324
+ * offline verifier when paired with a signed export.
1325
+ *
1326
+ * `query.types` is a comma-joined list (e.g.
1327
+ * `"evaluate.allow,policy.updated"`). `cursor` is the opaque
1328
+ * `next_cursor` from the prior page. All fields are optional; the
1329
+ * server defaults `limit` to 50 (capped at 500).
1330
+ *
1331
+ * Throws {@link AtlaSentError} on transport / auth failures — same
1332
+ * taxonomy as {@link AtlaSentClient.evaluate}.
1333
+ */
1334
+ listAuditEvents(query?: AuditEventsQuery): Promise<AuditEventsResult>;
1335
+ /**
1336
+ * Request a signed audit export bundle
1337
+ * (`POST /v1-audit/exports`). The returned object is wire-identical
1338
+ * with the server — `signature`, `chain_head_hash`, `events`, and
1339
+ * friends survive untouched so the bundle can be persisted to disk
1340
+ * and handed to the offline verifier (`verifyBundle` /
1341
+ * `verifyAuditBundle`) without any reshaping.
1342
+ *
1343
+ * Pass `filter.types`, `filter.from`, `filter.to`, or `filter.actor_id`
1344
+ * to narrow the export; omit for a full-org bundle. `rateLimit` is
1345
+ * attached alongside the wire fields for observability.
1346
+ *
1347
+ * Throws {@link AtlaSentError} on transport / auth failures — same
1348
+ * taxonomy as {@link AtlaSentClient.evaluate}.
1349
+ */
1350
+ createAuditExport(filter?: AuditExportRequest): Promise<AuditExportResult>;
1351
+ /**
1352
+ * Open a streaming evaluation session against `POST /v1-evaluate-stream`.
1353
+ *
1354
+ * Yields {@link StreamDecisionEvent} and {@link StreamProgressEvent} objects
1355
+ * as the server emits them. The iterator ends cleanly when the server sends
1356
+ * `event: done`; it throws {@link AtlaSentError} on transport errors or when
1357
+ * the server sends `event: error`.
1358
+ *
1359
+ * The final {@link StreamDecisionEvent} (isFinal: true) carries a `permitId`
1360
+ * suitable for passing to {@link verifyPermit} after the stream closes.
1361
+ *
1362
+ * Hardening:
1363
+ * - Throws {@link StreamTimeoutError} when no event arrives within
1364
+ * `opts.timeoutMs` (default 30 s). Pass `0` to disable.
1365
+ * - Retries up to `opts.maxRetries` times (default 3) with 1 s / 2 s / 4 s
1366
+ * delays on network drop (before a terminal event). Sends `Last-Event-ID`
1367
+ * on reconnect when the server has emitted event IDs.
1368
+ * - Throws {@link StreamParseError} on partial / malformed JSON rather than
1369
+ * crashing with a raw `SyntaxError`.
1370
+ * - Closes cleanly on `event: done` or a decision event with `done: true`.
1371
+ *
1372
+ * ```ts
1373
+ * for await (const event of client.protectStream({ agent, action })) {
1374
+ * if (event.type === "decision" && event.isFinal) {
1375
+ * await client.verifyPermit({ permitId: event.permitId });
1376
+ * }
1377
+ * }
1378
+ * ```
1379
+ */
1380
+ protectStream(input: EvaluateRequest, opts?: StreamOptions): AsyncIterable<StreamEvent>;
1381
+ private post;
1382
+ private get;
1383
+ private request;
1384
+ /**
1385
+ * Open a new HITL escalation. Bridges a `hold` outcome from
1386
+ * `protect()` to the approval queue: an agent that receives a
1387
+ * `hold` decision calls this to enroll the proposed action for
1388
+ * human review. The returned escalation can then be polled with
1389
+ * `getHitlEscalation()` or driven to terminal by
1390
+ * `approveHitlEscalation()` / `rejectHitlEscalation()`.
1391
+ *
1392
+ * Quorum, pool size, fallback decision and routing inherit from
1393
+ * the server-side policy when omitted from `input`.
1394
+ *
1395
+ * Calls `POST /v1/hitl`.
1396
+ */
1397
+ createHitlEscalation(input: HitlCreateRequest): Promise<{
1398
+ escalation: HitlEscalation;
1399
+ rateLimit: RateLimitState | null;
1400
+ }>;
1401
+ /**
1402
+ * List HITL escalations for the calling org. Defaults to
1403
+ * `status=pending`; pass `status` to query other queues
1404
+ * (`escalated`, `approved`, `rejected`, `auto_approved`,
1405
+ * `timed_out`).
1406
+ *
1407
+ * Calls `GET /v1/hitl`.
1408
+ */
1409
+ listHitlEscalations(input?: ListHitlEscalationsRequest): Promise<{
1410
+ data: ListHitlEscalationsResponse;
1411
+ rateLimit: RateLimitState | null;
1412
+ }>;
1413
+ /**
1414
+ * Get a HITL escalation. The server payload includes a live
1415
+ * `quorum_progress` snapshot when the escalation is still open.
1416
+ *
1417
+ * Calls `GET /v1/hitl/:id`.
1418
+ */
1419
+ getHitlEscalation(escalationId: string): Promise<{
1420
+ escalation: HitlEscalation;
1421
+ rateLimit: RateLimitState | null;
1422
+ }>;
1423
+ /**
1424
+ * List per-approver vote rows for an escalation.
1425
+ * Calls `GET /v1/hitl/:id/approvals`.
1426
+ */
1427
+ listHitlApprovals(escalationId: string): Promise<{
1428
+ approvals: HitlApprovalRecord[];
1429
+ rateLimit: RateLimitState | null;
1430
+ }>;
1431
+ /**
1432
+ * List the escalation chain hops for an escalation. Each `/escalate`
1433
+ * call appends one row.
1434
+ * Calls `GET /v1/hitl/:id/chain`.
1435
+ */
1436
+ getHitlChain(escalationId: string): Promise<{
1437
+ chain: HitlChainHop[];
1438
+ rateLimit: RateLimitState | null;
1439
+ }>;
1440
+ /**
1441
+ * Record an approve vote. Resolves the escalation only once the
1442
+ * server-side quorum count is satisfied; before that the response
1443
+ * carries a refreshed escalation row with the latest
1444
+ * `quorum_progress`.
1445
+ *
1446
+ * Calls `POST /v1/hitl/:id/approve`. The server returns 409
1447
+ * `duplicate_vote` if the same principal has already voted, and
1448
+ * 409 `already_rejected` if a concurrent reject crossed the line.
1449
+ */
1450
+ approveHitlEscalation(escalationId: string, input?: HitlApproveRequest): Promise<{
1451
+ escalation: HitlEscalation;
1452
+ rateLimit: RateLimitState | null;
1453
+ }>;
1454
+ /**
1455
+ * Record a reject vote. Reject is short-circuit terminal — a single
1456
+ * reject closes the escalation regardless of how many approves have
1457
+ * accumulated.
1458
+ *
1459
+ * Calls `POST /v1/hitl/:id/reject`.
1460
+ */
1461
+ rejectHitlEscalation(escalationId: string, input?: HitlRejectRequest): Promise<{
1462
+ escalation: HitlEscalation;
1463
+ rateLimit: RateLimitState | null;
1464
+ }>;
1465
+ /**
1466
+ * Re-route an open escalation to a higher tier. Bounded by the
1467
+ * escalation's `max_escalation_depth` — the server returns 409
1468
+ * `chain_exhausted` and applies the configured fallback decision
1469
+ * once the ceiling is hit.
1470
+ *
1471
+ * Calls `POST /v1/hitl/:id/escalate`.
1472
+ */
1473
+ escalateHitlEscalation(escalationId: string, input: HitlEscalateRequest): Promise<{
1474
+ escalation: HitlEscalation;
1475
+ rateLimit: RateLimitState | null;
1476
+ }>;
1477
+ /**
1478
+ * Manually apply the escalation's `fallback_decision`. Useful for
1479
+ * admin recovery of a hung escalation when the cron sweeper hasn't
1480
+ * run yet, or to short-circuit a stuck flow during incident
1481
+ * response.
1482
+ *
1483
+ * Calls `POST /v1/hitl/:id/timeout`.
1484
+ */
1485
+ timeoutHitlEscalation(escalationId: string): Promise<{
1486
+ escalation: HitlEscalation;
1487
+ rateLimit: RateLimitState | null;
1488
+ }>;
1489
+ /**
1490
+ * Run a named governance graph traversal query.
1491
+ *
1492
+ * Dispatches to `GET /v1/governance/graph/query?type=<queryType>`.
1493
+ * Each query type returns a different row shape — the return type
1494
+ * narrows automatically based on the literal `queryType` argument.
1495
+ *
1496
+ * `"user_approvals"` requires `params.actor_id` — the server returns
1497
+ * a 400 if it is absent.
1498
+ */
1499
+ queryGovernanceGraph<T extends GovernanceGraphQueryType>(queryType: T, params?: GovernanceGraphQueryParams): Promise<GovernanceGraphQueryResponse<T>>;
1500
+ /**
1501
+ * Reconstruct the multi-system execution timeline for a specific incident.
1502
+ *
1503
+ * Calls `GET /v1/governance/timeline/incident/{incidentId}`. Backed
1504
+ * server-side by `reconstruct_incident_chains_v2()`, which fixes the
1505
+ * `executor_id → actor_id` bug that silently produced empty timelines
1506
+ * in the original function.
1507
+ *
1508
+ * Returns full execution rows including the §13.1 columns
1509
+ * (`delegation_chain_id`, `replay_of_execution_id`, `incident_id`,
1510
+ * `policy_version_id`, `bundle_version_id`) alongside the actor
1511
+ * timeline and evidence rows.
1512
+ */
1513
+ getIncidentTimeline(incidentId: string): Promise<IncidentTimelineResponse>;
1514
+ /**
1515
+ * List connectors registered for the calling org.
1516
+ * Calls `GET /v1/governance/connectors`.
1517
+ */
1518
+ listConnectors(options?: {
1519
+ cursor?: string;
1520
+ limit?: number;
1521
+ }): Promise<ListConnectorsResponse>;
1522
+ /**
1523
+ * Register and install a new connector for the calling org.
1524
+ * Calls `POST /v1/governance/connectors`.
1525
+ */
1526
+ installConnector(input: InstallConnectorInput): Promise<InstallConnectorResponse>;
1527
+ /**
1528
+ * Store encrypted credentials for a connector.
1529
+ * Calls `POST /v1/governance/connectors/{id}/authenticate`.
1530
+ */
1531
+ authenticateConnector(connectorId: string, input: AuthenticateConnectorInput): Promise<AuthenticateConnectorResponse>;
1532
+ /**
1533
+ * Trigger an incremental sync for a connector.
1534
+ * Calls `POST /v1/governance/connectors/{id}/sync`.
1535
+ */
1536
+ syncConnector(connectorId: string): Promise<SyncConnectorResponse>;
1537
+ /**
1538
+ * Revoke a connector and all its associated credentials.
1539
+ * Calls `POST /v1/governance/connectors/{id}/revoke`.
1540
+ */
1541
+ revokeConnector(connectorId: string, reason?: string): Promise<RevokeConnectorResponse>;
1542
+ /**
1543
+ * Rotate the credentials for a connector.
1544
+ * Calls `POST /v1/governance/connectors/{id}/rotate-credentials`.
1545
+ */
1546
+ rotateConnectorCredentials(connectorId: string): Promise<RotateCredentialsResponse>;
1547
+ /**
1548
+ * List enforcement policies for the calling org, optionally filtered by connector type.
1549
+ * Calls `GET /v1/governance/enforcement-policies`.
1550
+ */
1551
+ listEnforcementPolicies(connectorType?: ConnectorType): Promise<ListEnforcementPoliciesResponse>;
1552
+ /**
1553
+ * Create or update a connector enforcement policy.
1554
+ * Calls `POST /v1/governance/enforcement-policies`.
1555
+ */
1556
+ upsertEnforcementPolicy(input: UpsertEnforcementPolicyInput): Promise<UpsertEnforcementPolicyResponse>;
1557
+ /**
1558
+ * Trigger a fresh org-level risk score computation.
1559
+ * Calls `POST /v1/governance/risk/compute`.
1560
+ */
1561
+ computeOrgRisk(options?: ComputeOrgRiskOptions): Promise<ComputeOrgRiskResponse>;
1562
+ /**
1563
+ * Retrieve the most recently computed risk score for the calling org.
1564
+ * Calls `GET /v1/governance/risk/latest`.
1565
+ */
1566
+ getLatestOrgRisk(): Promise<GetLatestOrgRiskResponse>;
1567
+ /**
1568
+ * Page through historical org risk scores, most-recent first.
1569
+ * Calls `GET /v1/governance/risk/history`.
1570
+ */
1571
+ listOrgRiskHistory(options?: {
1572
+ cursor?: string;
1573
+ limit?: number;
1574
+ }): Promise<ListOrgRiskHistoryResponse>;
1575
+ checkCrossOrgPermission(req: CrossOrgPermissionCheckRequest): Promise<CrossOrgPermissionCheckResult>;
1576
+ listCrossOrgPermissionChecks(params?: CrossOrgPermissionCheckListParams): Promise<CrossOrgPermissionCheckResult[]>;
1577
+ listAnomalyResponseRules(): Promise<AnomalyResponseRule[]>;
1578
+ createAnomalyResponseRule(req: CreateAnomalyResponseRuleRequest): Promise<AnomalyResponseRule>;
1579
+ updateAnomalyResponseRule(id: string, updates: Partial<CreateAnomalyResponseRuleRequest>): Promise<AnomalyResponseRule>;
1580
+ deleteAnomalyResponseRule(id: string): Promise<void>;
1581
+ triggerAnomalyResponse(req: TriggerAnomalyResponseRequest): Promise<AnomalyResponseEvent[]>;
1582
+ listAnomalyResponseEvents(params?: {
1583
+ limit?: number;
1584
+ execution_id?: string;
1585
+ }): Promise<AnomalyResponseEvent[]>;
1586
+ listBudgetExceptions(params?: {
1587
+ status?: BudgetExceptionStatus;
1588
+ budget_policy_id?: string;
1589
+ limit?: number;
1590
+ offset?: number;
1591
+ }): Promise<BudgetExceptionRequest[]>;
1592
+ getBudgetException(id: string): Promise<BudgetExceptionRequest>;
1593
+ createBudgetException(req: CreateBudgetExceptionRequest): Promise<BudgetExceptionRequest>;
1594
+ approveBudgetException(id: string, req: ApproveBudgetExceptionRequest): Promise<BudgetExceptionRequest>;
1595
+ rejectBudgetException(id: string, review_notes?: string): Promise<BudgetExceptionRequest>;
1596
+ cancelBudgetException(id: string): Promise<BudgetExceptionRequest>;
1597
+ listRegulatoryAuthorityLevels(): Promise<RegulatoryAuthorityLevel[]>;
1598
+ createRegulatoryAuthorityLevel(req: Omit<RegulatoryAuthorityLevel, "id" | "org_id" | "created_at">): Promise<RegulatoryAuthorityLevel>;
1599
+ listRegulatoryEscalations(params?: {
1600
+ status?: RegulatoryEscalationStatus;
1601
+ subject_type?: string;
1602
+ subject_id?: string;
1603
+ }): Promise<RegulatoryEscalation[]>;
1604
+ createRegulatoryEscalation(req: CreateRegulatoryEscalationRequest): Promise<RegulatoryEscalation>;
1605
+ acknowledgeRegulatoryEscalation(id: string): Promise<RegulatoryEscalation>;
1606
+ resolveRegulatoryEscalation(id: string, resolution: string, resolution_details?: Record<string, unknown>): Promise<RegulatoryEscalation>;
1607
+ overrideRegulatoryEscalation(id: string, reason: string): Promise<RegulatoryEscalation>;
1608
+ listSignalActions(signal_id: string): Promise<GovernanceSignalAction[]>;
1609
+ recordSignalAction(signal_id: string, req: RecordSignalActionRequest): Promise<GovernanceSignalAction>;
1610
+ recordSignalOutcome(signal_id: string, action_id: string, req: RecordSignalOutcomeRequest): Promise<GovernanceSignalAction>;
1611
+ getSignalActionSummary(): Promise<SignalActionSummary>;
1612
+ listImpersonationGrants(): Promise<CrossOrgImpersonationGrant[]>;
1613
+ createImpersonationGrant(req: CreateImpersonationGrantRequest): Promise<CrossOrgImpersonationGrant>;
1614
+ revokeImpersonationGrant(id: string): Promise<void>;
1615
+ issueImpersonationToken(grant_id: string, requested_duration_seconds?: number): Promise<ImpersonationToken>;
1616
+ validateImpersonationToken(token: string): Promise<ImpersonationValidationResult>;
1617
+ }
1618
+
1619
+ /** Node's webcrypto CryptoKey — kept local so the module doesn't depend on DOM types. */
1620
+ type WebCryptoKey = webcrypto.CryptoKey;
1621
+ /** Public key candidate the verifier will try, tagged with its registry id. */
1622
+ interface VerifyKey {
1623
+ keyId: string;
1624
+ publicKey: WebCryptoKey;
1625
+ }
1626
+ interface BundleVerificationResult {
1627
+ /**
1628
+ * AND of three checks: adjacency (each event's `previous_hash`
1629
+ * equals the prior event's `hash`), per-event hash recomputation
1630
+ * from the canonical payload, and `chain_head_hash` matching the
1631
+ * last event's stored hash.
1632
+ */
1633
+ chainIntegrityOk: boolean;
1634
+ /** Ed25519 signature verified against one of the supplied public keys. */
1635
+ signatureValid: boolean;
1636
+ /** `chain_head_hash` equals the last event's stored `hash`. */
1637
+ headHashMatches: boolean;
1638
+ /** Event ids whose recomputed hash != stored hash. */
1639
+ tamperedEventIds: string[];
1640
+ /** Which registry key id matched, when `signatureValid` is true. */
1641
+ matchedKeyId?: string | undefined;
1642
+ /** Non-fatal explanation when a flag is false. */
1643
+ reason?: string | undefined;
1644
+ /** Convenience: `chainIntegrityOk && signatureValid`. */
1645
+ verified: boolean;
1646
+ }
1647
+ /** Parsed bundle shape the verifier consumes. Fields beyond these are ignored. */
1648
+ interface AuditBundle {
1649
+ export_id?: unknown;
1650
+ org_id?: unknown;
1651
+ chain_head_hash?: unknown;
1652
+ event_count?: unknown;
1653
+ signed_at?: unknown;
1654
+ events?: unknown;
1655
+ signature?: unknown;
1656
+ signing_key_id?: unknown;
1657
+ [k: string]: unknown;
1658
+ }
1659
+ interface VerifyBundleOptions {
1660
+ /** SPKI-PEM strings (one per key in the active trust set). */
1661
+ publicKeysPem?: readonly string[];
1662
+ /** Already-imported keys, paired with registry ids (rotation hint). */
1663
+ keys?: readonly VerifyKey[];
1664
+ }
1665
+ /**
1666
+ * Reproduces `_shared/rules.ts::canonicalJSON` byte-for-byte:
1667
+ * - object keys sorted at every depth
1668
+ * - no whitespace
1669
+ * - `null`, `undefined`, `NaN`, `±Infinity` all render as `"null"`
1670
+ * - strings use standard `JSON.stringify` escapes
1671
+ */
1672
+ declare function canonicalJSON(value: unknown): string;
1673
+ /**
1674
+ * Recreate the exact bytes `handleExport` signed. Key order is
1675
+ * load-bearing — must match the object literal in
1676
+ * `v1-audit/index.ts::handleExport`. V8 preserves insertion order, so
1677
+ * the literal below is byte-identical with what the backend signs.
1678
+ */
1679
+ declare function signedBytesFor(bundle: AuditBundle): Uint8Array<ArrayBuffer>;
1680
+ declare function verifyAuditBundle(bundle: AuditBundle, keys: readonly VerifyKey[]): Promise<BundleVerificationResult>;
1681
+ /**
1682
+ * Load a bundle from disk (or a parsed object) and verify it.
1683
+ *
1684
+ * `publicKeysPem` is the active SPKI-PEM set from
1685
+ * `GET /v1-signing-keys`. When omitted, the chain check still runs
1686
+ * but `signatureValid` will be false with an explanatory `reason` —
1687
+ * callers that want a complete offline check MUST supply the trust
1688
+ * set.
1689
+ */
1690
+ declare function verifyBundle(pathOrBundle: string | AuditBundle, options?: VerifyBundleOptions): Promise<BundleVerificationResult>;
1691
+
1692
+ /**
1693
+ * `requirePermit` — higher-order execution gate for dangerous operations.
1694
+ *
1695
+ * Wraps any dangerous operation so it can only run after AtlaSent
1696
+ * authorizes it end-to-end (evaluate + verifyPermit). If authorization
1697
+ * is denied or the transport fails, the executor is never called.
1698
+ *
1699
+ * ```ts
1700
+ * import atlasent from "@atlasent/sdk";
1701
+ *
1702
+ * await atlasent.requirePermit(
1703
+ * {
1704
+ * action_type: "database.table.drop",
1705
+ * actor_id: "agent:code-agent",
1706
+ * resource_id: "prod-db.users",
1707
+ * environment: "production",
1708
+ * context: { reversibility: "irreversible", blast_radius: "customer_data" },
1709
+ * },
1710
+ * async () => {
1711
+ * await db.raw("DROP TABLE users");
1712
+ * },
1713
+ * );
1714
+ * ```
1715
+ *
1716
+ * Unlike calling the executor directly, dangerous code cannot bypass
1717
+ * this gate: if `requirePermit` throws, the executor never runs.
1718
+ */
1719
+ /**
1720
+ * Describes a potentially dangerous action to be authorized before
1721
+ * the executor runs. Passed as the first argument to {@link requirePermit}.
1722
+ */
1723
+ type ProtectedAction = {
1724
+ /** Namespaced action type — e.g. "database.table.drop". */
1725
+ action_type: string;
1726
+ /** Agent or user requesting the action — e.g. "agent:deploy-bot". */
1727
+ actor_id: string;
1728
+ /** Resource being acted upon — e.g. "prod-db.users". */
1729
+ resource_id: string;
1730
+ /** Target deployment environment. Controls policy strictness. */
1731
+ environment: "development" | "staging" | "production";
1732
+ /** Arbitrary risk context forwarded to the policy engine. */
1733
+ context: Record<string, unknown>;
1734
+ };
1735
+ /**
1736
+ * Authorize a dangerous operation before running it.
1737
+ *
1738
+ * Calls `protect` (evaluate + verifyPermit) with the {@link ProtectedAction}
1739
+ * descriptor. If authorization succeeds, calls `execute` and returns its
1740
+ * result. On any failure — policy deny, invalid permit, transport error —
1741
+ * `execute` is never called and the error propagates to the caller.
1742
+ *
1743
+ * This is the pattern primitive: dangerous code should be callable
1744
+ * **only** through this wrapper. In code review, any operation in the list
1745
+ * below is illegal unless it appears inside `requirePermit(...)`:
1746
+ *
1747
+ * - `db.raw(...)` / `DROP TABLE` / `DELETE FROM` / `TRUNCATE TABLE`
1748
+ * - `exec(...)` / `rm -rf` / `kubectl delete` / `terraform destroy`
1749
+ * - `stripe.transfers.create(...)` / `github.deployments.create(...)`
1750
+ * - `railway.volumes.delete(...)` / `supabase.from(...).delete()`
1751
+ */
1752
+ declare function requirePermit<T>(action: ProtectedAction, execute: () => Promise<T>): Promise<T>;
1753
+ /**
1754
+ * Classify a shell or database command as destructive.
1755
+ *
1756
+ * Returns the namespaced action type (e.g. `"destructive.command"`) when the
1757
+ * command matches a known dangerous pattern, or `null` when it appears safe.
1758
+ * Use the return value as `action_type` in a {@link requirePermit} call before
1759
+ * executing the command:
1760
+ *
1761
+ * ```ts
1762
+ * async function runCommand(command: string, actorId: string) {
1763
+ * const actionType = classifyCommand(command);
1764
+ * if (actionType) {
1765
+ * return requirePermit(
1766
+ * { action_type: actionType, actor_id: actorId, resource_id: command,
1767
+ * environment: "production", context: { command } },
1768
+ * () => exec(command),
1769
+ * );
1770
+ * }
1771
+ * return exec(command);
1772
+ * }
1773
+ * ```
1774
+ */
1775
+ declare function classifyCommand(command: string): string | null;
1776
+
1777
+ /**
1778
+ * `atlasent.withPermit(...)` — the lexically-scoped form of
1779
+ * {@link protect}. TypeScript mirror of the Python SDK's
1780
+ * ``atlasent.with_permit(...)``.
1781
+ *
1782
+ * Same execution-boundary contract as {@link protect}: evaluate +
1783
+ * verifyPermit run end-to-end before the executor is invoked, and the
1784
+ * executor cannot run unless a verified {@link Permit} was returned.
1785
+ * The difference is purely lexical — `withPermit` binds the execution
1786
+ * to the permit's lifetime via a callback, so the call site reads as
1787
+ * "execute this body under a permit" rather than "fetch a permit and
1788
+ * run code under it manually."
1789
+ *
1790
+ * ```ts
1791
+ * import atlasent from "@atlasent/sdk";
1792
+ *
1793
+ * const ok = await atlasent.withPermit(
1794
+ * {
1795
+ * agent: "deploy-bot",
1796
+ * action: "production.deploy",
1797
+ * context: { commit, approver },
1798
+ * },
1799
+ * async (permit) => {
1800
+ * const result = await runDeploy(commit);
1801
+ * return { ok: true, permitId: permit.permitId, result };
1802
+ * },
1803
+ * );
1804
+ * ```
1805
+ *
1806
+ * Pick the form that fits the call site:
1807
+ *
1808
+ * - {@link protect} when the caller wants the verified permit as a
1809
+ * value (e.g. to pass it across a process boundary, persist it
1810
+ * alongside their own record, or interleave it with non-trivial
1811
+ * control flow).
1812
+ * - {@link withPermit} when the action body is a single lexical scope
1813
+ * and "no permit, no execution" is the only thing the call site
1814
+ * needs to express.
1815
+ *
1816
+ * Both surfaces use the same underlying primitive and produce the
1817
+ * same audit-chain entry.
1818
+ */
1819
+
1820
+ /**
1821
+ * Authorize a request end-to-end and invoke `fn` only on a verified
1822
+ * permit.
1823
+ *
1824
+ * @param request Same shape as {@link ProtectRequest}.
1825
+ * @param fn Invoked with the verified {@link Permit}. Its return
1826
+ * value (awaited if it is a promise) is propagated to the caller.
1827
+ *
1828
+ * @returns Whatever `fn` returns.
1829
+ *
1830
+ * @throws {AtlaSentDeniedError} Policy denied, hold/escalate, or
1831
+ * permit failed verification. `fn` is never invoked.
1832
+ * @throws {AtlaSentError} Transport, timeout, auth, rate-limit, or
1833
+ * server error. `fn` is never invoked.
1834
+ *
1835
+ * Errors thrown inside `fn` propagate untouched — the permit is
1836
+ * already consumed by the verify step in v1, so there is no
1837
+ * compensating revoke.
1838
+ */
1839
+ declare function withPermit<T>(request: ProtectRequest, fn: (permit: Permit) => Promise<T> | T): Promise<T>;
1840
+
1841
+ /**
1842
+ * Sandbox simulation diff — wire shape for `GET /v1/agent-sandbox/:id/diff`.
1843
+ *
1844
+ * Mirrors the `export_sandbox_diff()` SQL function added in migration
1845
+ * 20260509120000. Lets a caller render a sandbox-vs-live preview
1846
+ * before promoting a simulation to a real execution. Once a sandbox
1847
+ * run reaches a terminal status it is auto-torn-down; a follow-up
1848
+ * call returns the {@link SandboxDiffEmpty} shape so the UI can
1849
+ * surface "this run has been finalised" without a 404.
1850
+ */
1851
+ type SandboxRunMode = "dry_run" | "simulation" | "constrained_execution" | "production_execution";
1852
+ type SandboxRunStatus = "pending" | "running" | "completed" | "failed" | "cancelled" | "timed_out";
1853
+ type SandboxWriteOp = "insert" | "update" | "delete";
1854
+ interface SandboxRunWrite {
1855
+ sequence: number;
1856
+ live_table: string;
1857
+ live_pk: string | null;
1858
+ op: SandboxWriteOp;
1859
+ payload_before: Record<string, unknown> | null;
1860
+ payload_after: Record<string, unknown> | null;
1861
+ metadata: Record<string, unknown>;
1862
+ created_at: string;
1863
+ }
1864
+ interface SandboxDiffPerTable {
1865
+ total: number;
1866
+ insert: number;
1867
+ update: number;
1868
+ delete: number;
1869
+ }
1870
+ /** Returned when staging rows are still present for the run. */
1871
+ interface SandboxDiff {
1872
+ simulation_run_id: string;
1873
+ org_id: string;
1874
+ final_status: SandboxRunStatus;
1875
+ mode: SandboxRunMode;
1876
+ total_writes: number;
1877
+ /** Keyed by live table name. */
1878
+ summary: Record<string, SandboxDiffPerTable>;
1879
+ writes: SandboxRunWrite[];
1880
+ }
1881
+ /**
1882
+ * Returned when the run has been torn down — staging rows are gone
1883
+ * and the audit-log `agent_sandbox.teardown` event is the only
1884
+ * post-mortem record.
1885
+ */
1886
+ interface SandboxDiffEmpty {
1887
+ simulation_run_id: string;
1888
+ status: SandboxRunStatus;
1889
+ mode: SandboxRunMode;
1890
+ torn_down: boolean;
1891
+ total_writes: 0;
1892
+ summary: Record<string, never>;
1893
+ writes: [];
1894
+ }
1895
+ type SandboxDiffResponse = SandboxDiff | SandboxDiffEmpty;
1896
+ /**
1897
+ * `true` when the response carries staging rows (i.e. the run has not
1898
+ * been torn down yet). Narrow before reading `summary` / `writes`.
1899
+ */
1900
+ declare function isSandboxDiffPopulated(r: SandboxDiffResponse): r is SandboxDiff;
1901
+
1902
+ /**
1903
+ * Delegation revocation propagation — wire shape for the
1904
+ * `propagate_delegation_revocation()` summary returned by
1905
+ * `/v1/authority-delegations/:id/revoke` (and emitted as the
1906
+ * `authority_delegation.propagated` audit event).
1907
+ *
1908
+ * Mirrors migration 20260509120001. The propagator is invoked
1909
+ * automatically on `status -> revoked` via DB trigger; consumers
1910
+ * see the summary either as the audit-event payload (asynchronous)
1911
+ * or attached to the revoke response (synchronous).
1912
+ */
1913
+ interface DelegationPropagationSummary {
1914
+ delegation_id: string;
1915
+ /** `[delegator_user_id, delegate_user_id]` — uuids as strings. */
1916
+ principals: [string, string];
1917
+ /** Phase-B role-justified delegations carry the role; user-justified
1918
+ * delegations omit it. */
1919
+ delegator_role?: string | null;
1920
+ hitl_reassigned: number;
1921
+ financial_invalidated: number;
1922
+ policies_flagged: number;
1923
+ revoked_reason?: string | null;
1924
+ }
1925
+ /**
1926
+ * Convenience predicate: `true` when the revocation produced any
1927
+ * downstream effect. Useful for "are we sure?" UI guards before
1928
+ * surfacing the summary toast.
1929
+ */
1930
+ declare function delegationPropagationHadEffect(s: DelegationPropagationSummary): boolean;
1931
+
1932
+ /**
1933
+ * Public types for the AtlaSent **Identity Assertion** — a signed
1934
+ * attestation from an identity provider (OIDC / SSO) that the
1935
+ * reviewer named in an approval_artifact.v1 is a real human with a
1936
+ * specific role.
1937
+ *
1938
+ * Wire-stable as `identity_assertion.v1`. The contract lives in
1939
+ * `contract/schemas/identity-assertion.schema.json`. Verification is
1940
+ * server-side inside `/v1-evaluate`; the SDK exposes the types so
1941
+ * callers can construct or inspect the `identity_assertion` block on
1942
+ * an approval artifact.
1943
+ *
1944
+ * Why this matters: without identity attestation the artifact's
1945
+ * `reviewer.principal_kind: "human"` is a self-claim from the
1946
+ * approval issuer alone. With it, the IdP independently vouches for
1947
+ * the human — a separate trust root, defence in depth.
1948
+ */
1949
+
1950
+ /** Identity-attested subject of the assertion. The verifier requires
1951
+ * `principal_kind === "human"`; the other variants exist so the
1952
+ * schema can structurally describe denied/declined assertions. */
1953
+ interface IdentitySubject {
1954
+ principal_id: string;
1955
+ principal_kind: PrincipalKind;
1956
+ }
1957
+ /** Cryptographic binding tying the assertion to a specific approval. */
1958
+ interface IdentityAssertionBinding {
1959
+ /** Must equal artifact.approval_id. */
1960
+ approval_id: string;
1961
+ /** Must equal the canonical action hash. */
1962
+ action_hash: string;
1963
+ /** Must equal the request's tenant_id. */
1964
+ tenant_id: string;
1965
+ /** Must equal the request's environment. Empty string allowed when
1966
+ * the verifier was not given one (explicit equality, no implicit
1967
+ * broadening). */
1968
+ environment: string;
1969
+ }
1970
+ /** Identity issuer (the IdP). Always OIDC-shaped. */
1971
+ interface IdentityIssuer {
1972
+ type: "oidc";
1973
+ issuer_id: string;
1974
+ /** Key id for rotation; looked up in IDENTITY_TRUSTED_ISSUERS. */
1975
+ kid: string;
1976
+ }
1977
+ /** A complete signed identity assertion. */
1978
+ interface IdentityAssertionV1 {
1979
+ version: "identity_assertion.v1";
1980
+ subject: IdentitySubject;
1981
+ /** Required role attested by the IdP (e.g. "qa_reviewer"). */
1982
+ role: string;
1983
+ binding: IdentityAssertionBinding;
1984
+ issuer: IdentityIssuer;
1985
+ issued_at: string;
1986
+ expires_at: string;
1987
+ /** Optional anti-replay nonce. The approval-artifact nonce is the
1988
+ * primary defence; deployments wanting assertion-level replay
1989
+ * protection ledger this separately. */
1990
+ nonce?: string;
1991
+ signature: string;
1992
+ }
1993
+ /** Per-issuer entry in IDENTITY_TRUSTED_ISSUERS. Server-side config
1994
+ * only — never on the wire. The SDK exposes the type so operators
1995
+ * can lint config in CI. */
1996
+ interface IdentityIssuerKey {
1997
+ alg: "HS256" | "Ed25519";
1998
+ key: string;
1999
+ /** Per-issuer scope: roles this kid may attest. Empty/missing = unscoped. */
2000
+ allowed_roles?: string[];
2001
+ /** Per-issuer scope: environments this kid may attest in. Empty/missing = unscoped. */
2002
+ allowed_environments?: string[];
2003
+ }
2004
+ /** JSON shape of IDENTITY_TRUSTED_ISSUERS. Keyed by issuer_id then by
2005
+ * kid. Independent trust root from APPROVAL_TRUSTED_ISSUERS. */
2006
+ type IdentityTrustedIssuersConfig = Record<string, Record<string, IdentityIssuerKey>>;
2007
+
2008
+ /**
2009
+ * Public types for the AtlaSent **Approval Artifact** — a signed
2010
+ * attestation that a *human* reviewer approved a specific action.
2011
+ *
2012
+ * Wire-stable as `approval_artifact.v1`. The contract lives in
2013
+ * `contract/schemas/approval-artifact.schema.json`. Verification is
2014
+ * server-side inside `/v1-evaluate`; the SDK exposes the types so
2015
+ * callers can construct the `approval` field on an evaluate request.
2016
+ *
2017
+ * Why this matters: the calling agent cannot self-declare authority
2018
+ * by passing reviewer flags in `context`. The artifact is bound to
2019
+ * the exact action via `action_hash`, signed by a trusted issuer,
2020
+ * and replay-protected via `nonce`.
2021
+ */
2022
+ /** What kind of principal performed the approval. */
2023
+ type PrincipalKind = "human" | "agent" | "service_account";
2024
+ /** Identity of the reviewer recorded inside the artifact. */
2025
+ interface ApprovalReviewer {
2026
+ principal_id: string;
2027
+ principal_kind: PrincipalKind;
2028
+ email?: string;
2029
+ groups?: string[];
2030
+ roles?: string[];
2031
+ }
2032
+ /** Trusted issuer identification — used to look up the verification key. */
2033
+ interface ApprovalIssuer {
2034
+ type: "oidc" | "approval_service";
2035
+ issuer_id: string;
2036
+ kid: string;
2037
+ }
2038
+
2039
+ /**
2040
+ * The full signed approval artifact. Producers (approval services)
2041
+ * compute `action_hash` over the canonical action payload and sign
2042
+ * the artifact with the `signature` field stripped; the SDK does not
2043
+ * sign or verify, it only carries the artifact to the server.
2044
+ *
2045
+ * `identity_assertion` is REQUIRED on the wire whenever
2046
+ * `/v1-evaluate` calls the verifier with `requireIdentityAssertion:
2047
+ * true` — i.e. when human approval is required. Without it, the
2048
+ * server returns deny:`missing identity assertion`. The SDK type
2049
+ * keeps the field optional to support shadow / preflight flows that
2050
+ * inspect an artifact without verifying.
2051
+ */
2052
+ interface ApprovalArtifactV1 {
2053
+ version: "approval_artifact.v1";
2054
+ approval_id: string;
2055
+ tenant_id: string;
2056
+ action_type: string;
2057
+ resource_id: string;
2058
+ action_hash: string;
2059
+ reviewer: ApprovalReviewer;
2060
+ issuer: ApprovalIssuer;
2061
+ issued_at: string;
2062
+ expires_at: string;
2063
+ nonce: string;
2064
+ signature: string;
2065
+ identity_assertion?: IdentityAssertionV1;
2066
+ }
2067
+ /**
2068
+ * Optional `approval` field on an evaluate request. Either embed the
2069
+ * full artifact, or pass an `approval_id` and let the server resolve
2070
+ * it from a side channel (preferred when the artifact is large).
2071
+ */
2072
+ interface ApprovalReference {
2073
+ approval_id?: string;
2074
+ artifact?: ApprovalArtifactV1;
2075
+ }
2076
+
2077
+ /**
2078
+ * Public types for the AtlaSent **Approval Quorum** — the additive
2079
+ * layer that lets multiple individually-trustworthy approvals be
2080
+ * combined into a single quorum package.
2081
+ *
2082
+ * Wire-stable as `approval_quorum.v1`. The contract lives in
2083
+ * `contract/schemas/approval-quorum.schema.json`. Verification is
2084
+ * server-side inside `/v1-evaluate`; the SDK exposes the types so
2085
+ * callers can construct a quorum payload before submitting.
2086
+ *
2087
+ * Important invariant (locked): quorum does NOT relax artifact
2088
+ * verification. Every approval inside a quorum package must first
2089
+ * pass the locked single-approval verifier (artifact signature +
2090
+ * identity assertion + every binding) BEFORE quorum-level policy is
2091
+ * evaluated. If any single approval fails, the whole package is
2092
+ * denied with that approval's exact reason — no fallthrough.
2093
+ */
2094
+
2095
+ /** Independence constraints on a quorum policy. Duplicate
2096
+ * `reviewer.principal_id` is ALWAYS rejected regardless of these
2097
+ * flags; these strengthen the requirement further. */
2098
+ interface QuorumIndependence {
2099
+ /** When true, requires distinct *approval-issuer* identities so
2100
+ * two tokens minted by the same QA system don't count separately
2101
+ * even if signed for different reviewers. */
2102
+ distinct_approval_issuers?: boolean;
2103
+ /** When true, requires distinct *identity-issuer* identities so
2104
+ * collusion between IdPs vouching for the same effective
2105
+ * reviewer pool is harder. */
2106
+ distinct_identity_issuers?: boolean;
2107
+ }
2108
+ /** A single role × count requirement in a quorum policy. */
2109
+ interface QuorumRoleRequirement {
2110
+ role: string;
2111
+ /** Minimum number of approvals carrying this role. */
2112
+ min: number;
2113
+ }
2114
+ /** Quorum policy describing what counts as passing. */
2115
+ interface QuorumPolicy {
2116
+ /** Minimum total approvals (regardless of role). */
2117
+ required_count: number;
2118
+ /** OPTIONAL role-mix requirements; each is checked independently. */
2119
+ required_role_mix?: QuorumRoleRequirement[];
2120
+ /** Independence constraints. Duplicate principal_id is always
2121
+ * rejected; these flags additionally require distinct issuers. */
2122
+ independence?: QuorumIndependence;
2123
+ /** OPTIONAL package-level staleness window in seconds. Layered on
2124
+ * top of each artifact's own `expires_at` — both must be in the
2125
+ * future. */
2126
+ max_age_seconds?: number;
2127
+ }
2128
+ /** A signed quorum package carrying multiple approvals. */
2129
+ interface ApprovalQuorumV1 {
2130
+ version: "approval_quorum.v1";
2131
+ tenant_id: string;
2132
+ /** Canonical action hash. Must match every approval's action_hash
2133
+ * and the verifier's expected_action_hash. */
2134
+ action_hash: string;
2135
+ environment: string;
2136
+ issued_at: string;
2137
+ policy: QuorumPolicy;
2138
+ /** The approvals being counted. Each is a full ApprovalArtifactV1
2139
+ * carrying its own identity_assertion. */
2140
+ approvals: ApprovalArtifactV1[];
2141
+ }
2142
+ /** Cryptographic proof material returned on a passing quorum.
2143
+ * Persisted on the audit row so external auditors can reconstruct
2144
+ * WHO approved together without per-approval row joins. */
2145
+ interface QuorumProof {
2146
+ /** sha256(canonical({ version, tenant_id, action_hash, environment,
2147
+ * issued_at, policy, sorted approval_hashes })). */
2148
+ quorum_hash: string;
2149
+ /** approval_id of every counted approval, in the order they were
2150
+ * submitted. */
2151
+ approval_ids: string[];
2152
+ }
2153
+
2154
+ /**
2155
+ * Shared V1 API wire types used across multiple SDK modules.
2156
+ *
2157
+ * These reflect the canonical domain objects returned by the
2158
+ * atlasent-control-plane V1 API. Import from here to avoid circular
2159
+ * dependencies between proof.ts, overrides.ts, and types.ts.
2160
+ */
2161
+ /**
2162
+ * Canonical Permit domain object as returned by the V1 API.
2163
+ *
2164
+ * All timestamps are ISO-8601 UTC strings.
2165
+ *
2166
+ * This is the richer V1 shape returned by `GET /v1/permits/:id` and
2167
+ * embedded in proof bundles. It differs from the legacy `PermitRecord`
2168
+ * in `types.ts` which uses snake_case and legacy fields from the
2169
+ * Supabase function surface.
2170
+ */
2171
+ interface PermitV1 {
2172
+ id: string;
2173
+ orgId: string;
2174
+ /** Who the permit was issued for (actor or agent ID). */
2175
+ subject: string;
2176
+ /** What the permit grants (action/resource scope). */
2177
+ scope: string;
2178
+ status: "active" | "revoked" | "expired";
2179
+ /** The evaluation that produced this permit, or `null` for admin issuance. */
2180
+ evaluationId: string | null;
2181
+ /** Actor who issued the permit (system or admin). */
2182
+ issuedBy: string;
2183
+ /** Actor who revoked the permit, or `null`. */
2184
+ revokedBy: string | null;
2185
+ /** ISO-8601 issuance timestamp. */
2186
+ issuedAt: string;
2187
+ /** ISO-8601 revocation timestamp, or `null`. */
2188
+ revokedAt: string | null;
2189
+ /** ISO-8601 expiry timestamp, or `null` if the permit does not expire. */
2190
+ expiresAt: string | null;
2191
+ /** Arbitrary key/value metadata. `null` when none. */
2192
+ metadata: Record<string, unknown> | null;
2193
+ }
2194
+ /**
2195
+ * Canonical governance event as stored in the event log.
2196
+ *
2197
+ * `type` is a dotted domain-prefixed string, e.g. `override.created`,
2198
+ * `permit.revoked`, `evaluation.decided`.
2199
+ *
2200
+ * `actorId` is `null` for system-emitted events (expiry sweeps, etc.).
2201
+ */
2202
+ interface GovernanceEvent {
2203
+ id: string;
2204
+ type: string;
2205
+ actorId: string | null;
2206
+ orgId: string;
2207
+ /** ISO-8601 timestamp. */
2208
+ at: string;
2209
+ /** Event-type-specific payload. Optional — shape varies by `type`. */
2210
+ payload?: Record<string, unknown>;
2211
+ }
2212
+
2213
+ /**
2214
+ * Override types — wire shapes for `/v1/overrides`.
2215
+ *
2216
+ * Overrides allow an authorized actor to bypass a deny decision for a
2217
+ * specific evaluation. They must be approved before they take effect
2218
+ * and can be revoked at any time.
2219
+ *
2220
+ * Mirrors `api/src/schemas/overrides.ts` in atlasent-control-plane.
2221
+ */
2222
+ /**
2223
+ * Lifecycle status of an override request.
2224
+ *
2225
+ * - `pending` — created, waiting for approval
2226
+ * - `approved` — approved and active; the evaluation's deny is lifted
2227
+ * - `revoked` — manually revoked
2228
+ * - `expired` — TTL elapsed before revocation
2229
+ */
2230
+ type OverrideStatus = "pending" | "approved" | "revoked" | "expired";
2231
+ /**
2232
+ * The event types that can appear on an override's event log.
2233
+ */
2234
+ type OverrideEventType = "created" | "approved" | "revoked";
2235
+ /**
2236
+ * Canonical Override domain object returned by the API.
2237
+ *
2238
+ * All timestamps are ISO-8601 UTC strings. Nullable fields are `null`
2239
+ * rather than omitted so wire shapes are stable.
2240
+ */
2241
+ interface OverrideV1 {
2242
+ id: string;
2243
+ orgId: string;
2244
+ /** The evaluation ID this override applies to. */
2245
+ evaluationId: string;
2246
+ /** Human-readable justification provided at creation time. */
2247
+ reason: string;
2248
+ status: OverrideStatus;
2249
+ /** Actor who requested the override. */
2250
+ requestedBy: string;
2251
+ /** Actor who approved the override, or `null` if not yet approved. */
2252
+ approvedBy: string | null;
2253
+ /** Actor who revoked the override, or `null` if not revoked. */
2254
+ revokedBy: string | null;
2255
+ /** ISO-8601 creation timestamp. */
2256
+ createdAt: string;
2257
+ /** ISO-8601 approval timestamp, or `null`. */
2258
+ approvedAt: string | null;
2259
+ /** ISO-8601 revocation timestamp, or `null`. */
2260
+ revokedAt: string | null;
2261
+ /** ISO-8601 expiry timestamp, or `null` if no TTL was set. */
2262
+ expiresAt: string | null;
2263
+ /** Arbitrary key/value metadata attached at creation. `null` when none. */
2264
+ metadata: Record<string, unknown> | null;
2265
+ }
2266
+ /**
2267
+ * Paginated list of overrides.
2268
+ */
2269
+ interface OverrideListResponse {
2270
+ items: OverrideV1[];
2271
+ /** Opaque cursor for the next page. `null` when there are no more results. */
2272
+ nextCursor: string | null;
2273
+ }
2274
+ /**
2275
+ * Input for `POST /v1/overrides` — request a new override.
2276
+ */
2277
+ interface CreateOverrideRequest {
2278
+ /** Human-readable justification. Required; max 2000 characters. */
2279
+ reason: string;
2280
+ /** The evaluation ID to override. */
2281
+ evaluationId: string;
2282
+ /** Lifetime in seconds. Defaults to 3600. Max 604800 (7 days). */
2283
+ ttlSeconds?: number;
2284
+ /** Arbitrary metadata to attach to the override record. */
2285
+ metadata?: Record<string, unknown>;
2286
+ }
2287
+ /**
2288
+ * Audit event appended to an override's event log on every state mutation.
2289
+ */
2290
+ interface OverrideEvent {
2291
+ id: string;
2292
+ overrideId: string;
2293
+ orgId: string;
2294
+ /** Actor who caused this event. */
2295
+ actorId: string;
2296
+ type: OverrideEventType;
2297
+ /** ISO-8601 timestamp. */
2298
+ at: string;
2299
+ /** Event-specific payload. `null` when none. */
2300
+ payload: Record<string, unknown> | null;
2301
+ }
2302
+ /**
2303
+ * Response for `GET /v1/overrides/:id/events`.
2304
+ */
2305
+ interface OverrideEventsResponse {
2306
+ items: OverrideEvent[];
2307
+ }
2308
+
2309
+ /**
2310
+ * Proof bundle types — wire shape for `GET /v1/proof/:evaluationId`.
2311
+ *
2312
+ * The proof endpoint reconstructs an evaluation from the governance event
2313
+ * log and returns it along with the associated permits, overrides, and events
2314
+ * as a signed bundle. Consumers use this for tamper-evident audit trails.
2315
+ *
2316
+ * Mirrors `api/src/schemas/proof.ts` in atlasent-control-plane.
2317
+ */
2318
+
2319
+ /**
2320
+ * Reconstructed summary of the evaluation that produced the proof.
2321
+ *
2322
+ * Drawn from the `evaluation.decided` governance event. Timestamps
2323
+ * are ISO-8601 UTC strings.
2324
+ */
2325
+ interface ProofEvaluationSummary {
2326
+ evaluationId: string;
2327
+ /** Policy decision: `"allow"` or `"deny"`. */
2328
+ decision: "allow" | "deny";
2329
+ /** Human-readable reasons emitted by the policy engine. */
2330
+ reasons: string[];
2331
+ /** The action that was evaluated. `null` when not stored on the event. */
2332
+ action: string | null;
2333
+ /** Resource type. `null` when not stored on the event. */
2334
+ resourceType: string | null;
2335
+ /** Resource identifier. `null` when not stored on the event. */
2336
+ resourceId: string | null;
2337
+ /** ISO-8601 timestamp of when the decision was made. */
2338
+ decidedAt: string;
2339
+ /** Actor who triggered the evaluation. `null` for system-initiated evaluations. */
2340
+ decidedBy: string | null;
2341
+ }
2342
+ /**
2343
+ * The proof payload — the data that is signed.
2344
+ *
2345
+ * Contains the reconstructed evaluation summary, the permits and overrides
2346
+ * that were active at decision time, and the full governance event trail.
2347
+ */
2348
+ interface ProofPayload {
2349
+ evaluation: ProofEvaluationSummary;
2350
+ permits: PermitV1[];
2351
+ overrides: OverrideV1[];
2352
+ events: GovernanceEvent[];
2353
+ }
2354
+ /**
2355
+ * Full proof bundle returned by `GET /v1/proof/:evaluationId`.
2356
+ *
2357
+ * **Signature semantics:**
2358
+ *
2359
+ * When `PROOF_SIGNING_SECRET` is configured on the server:
2360
+ * - `algorithm === "hmac-sha256"`
2361
+ * - `signature` is the hex-encoded HMAC-SHA256 over
2362
+ * `evaluationId + "\n" + issuedAt + "\n" + JSON.stringify(payload)`
2363
+ *
2364
+ * When `PROOF_SIGNING_SECRET` is absent:
2365
+ * - `algorithm === "none"`, `signature === null`
2366
+ *
2367
+ * Consumers MUST reject proofs where `algorithm === "none"` in any
2368
+ * context where tamper-evidence is required.
2369
+ */
2370
+ interface ProofResponse {
2371
+ evaluationId: string;
2372
+ /** Signing algorithm used. `"none"` means unsigned. */
2373
+ algorithm: "none" | "hmac-sha256";
2374
+ /** Hex-encoded HMAC-SHA256 signature, or `null` when unsigned. */
2375
+ signature: string | null;
2376
+ payload: ProofPayload;
2377
+ /** ISO-8601 timestamp of when the proof was issued. */
2378
+ issuedAt: string;
2379
+ }
2380
+
2381
+ /**
2382
+ * Financial Action Model — canonical types for financial execution authority.
2383
+ *
2384
+ * Defines the core vocabulary for all financial actions governed by
2385
+ * AtlaSent's economic governance layer. Every consequential financial
2386
+ * operation must be classified here before execution authorization.
2387
+ *
2388
+ * Wire-stable as `financial_action.v1`.
2389
+ */
2390
+ /** ISO 4217 currency code. */
2391
+ type CurrencyCode = "USD" | "EUR" | "GBP" | "JPY" | "CAD" | "AUD" | "CHF" | "CNY" | "SEK" | "NZD" | string;
2392
+ /**
2393
+ * Risk tier for a financial action.
2394
+ *
2395
+ * - low: < $1,000 — single-approver sufficient
2396
+ * - medium: $1,000–$50,000 — dual-control typically required
2397
+ * - high: $50,000–$1,000,000 — CFO-level required
2398
+ * - critical: > $1,000,000 or irreversible — board-level or emergency protocol
2399
+ */
2400
+ type FinancialRiskTier = "low" | "medium" | "high" | "critical";
2401
+ /** How accountability is distributed across parties for a financial action. */
2402
+ type LiabilityClassification = "individual" | "shared" | "delegated" | "supervisory" | "emergency_override";
2403
+ /** Canonical set of financial action types. */
2404
+ type FinancialActionType = "refund" | "payment_release" | "invoice_approval" | "payroll_execution" | "procurement_approval" | "wire_transfer" | "trading_execution" | "budget_override" | "spending_authorization" | "vendor_payment" | "subscription_cancellation" | "credit_issuance" | "fee_waiver" | "chargeback" | "contract_commitment" | string;
2405
+ /**
2406
+ * Canonical definition of a financial action class.
2407
+ *
2408
+ * Stored in `financial_action_classes`. Drives quorum policy,
2409
+ * liability classification, and risk tier assignment.
2410
+ */
2411
+ interface FinancialActionClass {
2412
+ /** Stable identifier (e.g. "wire_transfer.domestic"). */
2413
+ readonly action_class_id: string;
2414
+ readonly name: string;
2415
+ readonly action_type: FinancialActionType;
2416
+ readonly risk_tier: FinancialRiskTier;
2417
+ /** Minimum number of approvals before execution is permitted. */
2418
+ readonly required_approvals: number;
2419
+ readonly liability_classification: LiabilityClassification;
2420
+ /** Whether this action is reversible post-execution. */
2421
+ readonly reversible: boolean;
2422
+ /** Maximum allowed execution value for autonomous agents (null = no ceiling). */
2423
+ readonly autonomous_ceiling: number | null;
2424
+ readonly ceiling_currency: CurrencyCode | null;
2425
+ readonly created_at: string;
2426
+ readonly description?: string;
2427
+ }
2428
+ /** Status of a financial execution record. */
2429
+ type FinancialExecutionStatus = "pending_approval" | "approved" | "executing" | "completed" | "failed" | "reversed" | "disputed" | "frozen";
2430
+ /**
2431
+ * Immutable record of a financial action execution.
2432
+ *
2433
+ * Written at authorization time. Stored in `financial_execution_records`.
2434
+ */
2435
+ interface FinancialExecutionRecord {
2436
+ readonly execution_id: string;
2437
+ readonly action_class_id: string;
2438
+ readonly org_id: string;
2439
+ readonly action_value: number;
2440
+ readonly currency: CurrencyCode;
2441
+ readonly risk_tier: FinancialRiskTier;
2442
+ readonly liability_classification: LiabilityClassification;
2443
+ readonly initiator_id: string;
2444
+ readonly executor_id: string;
2445
+ /** Ordered list of approver IDs. */
2446
+ readonly approver_ids: readonly string[];
2447
+ /** AtlaSent permit IDs — one per approval stage. */
2448
+ readonly permit_ids: readonly string[];
2449
+ readonly override_applied: boolean;
2450
+ readonly override_id: string | null;
2451
+ readonly status: FinancialExecutionStatus;
2452
+ readonly authorized_at: string;
2453
+ readonly executed_at: string | null;
2454
+ /** Hash-chained audit trail entry. */
2455
+ readonly audit_hash: string;
2456
+ readonly context: Record<string, unknown>;
2457
+ }
2458
+ /** Threshold configuration for risk-tier escalation. */
2459
+ interface RiskTierThreshold {
2460
+ readonly tier: FinancialRiskTier;
2461
+ /** Inclusive lower bound in the reference currency. */
2462
+ readonly lower_bound: number;
2463
+ /** Exclusive upper bound; null means unbounded. */
2464
+ readonly upper_bound: number | null;
2465
+ readonly reference_currency: CurrencyCode;
2466
+ }
2467
+ /** Default risk tier thresholds (USD-denominated). */
2468
+ declare const DEFAULT_RISK_TIER_THRESHOLDS: readonly RiskTierThreshold[];
2469
+ /**
2470
+ * Classify a financial action's risk tier based on its value.
2471
+ */
2472
+ declare function classifyRiskTier(value: number, thresholds?: readonly RiskTierThreshold[]): FinancialRiskTier;
2473
+ /**
2474
+ * Return true when the action value is within the autonomous execution ceiling.
2475
+ * A null ceiling means no ceiling is configured (always within bounds).
2476
+ */
2477
+ declare function withinAutonomousCeiling(actionValue: number, ceiling: number | null): boolean;
2478
+
2479
+ /**
2480
+ * Liability Attribution Engine.
2481
+ *
2482
+ * Tracks and computes liability across the full chain of parties involved
2483
+ * in a financial action: who authorized, delegated, executed, overrode,
2484
+ * and approved exceptions.
2485
+ *
2486
+ * Supports shared, delegated, supervisory, and emergency-override liability
2487
+ * regimes. Every attribution record is immutable once written.
2488
+ *
2489
+ * Wire-stable as `liability_attribution.v1`.
2490
+ */
2491
+
2492
+ /** The role a party played in a financial action. */
2493
+ type LiabilityPartyRole = "authorizer" | "delegator" | "delegate" | "executor" | "approver" | "override_actor" | "supervisor" | "exception_approver";
2494
+ /** A single party in the liability chain. */
2495
+ interface LiabilityParty {
2496
+ readonly party_id: string;
2497
+ readonly party_label: string;
2498
+ readonly party_type: "human" | "agent" | "system";
2499
+ readonly role: LiabilityPartyRole;
2500
+ /** Fractional liability weight (0–1); all parties in chain sum to 1. */
2501
+ readonly liability_weight: number;
2502
+ readonly acted_at: string;
2503
+ readonly permit_id: string | null;
2504
+ }
2505
+ /**
2506
+ * Immutable liability attribution record for a financial execution.
2507
+ *
2508
+ * Stored in `liability_attribution_records`. One record per execution.
2509
+ */
2510
+ interface LiabilityAttributionRecord {
2511
+ readonly attribution_id: string;
2512
+ readonly execution_id: string;
2513
+ readonly org_id: string;
2514
+ readonly classification: LiabilityClassification;
2515
+ readonly risk_tier: FinancialRiskTier;
2516
+ /** Ordered liability chain. First party = primary. */
2517
+ readonly liability_chain: readonly LiabilityParty[];
2518
+ readonly delegation_present: boolean;
2519
+ readonly supervisory_present: boolean;
2520
+ readonly emergency_override: boolean;
2521
+ readonly override_justification: string | null;
2522
+ readonly created_at: string;
2523
+ /** SHA-256 hash of the canonical chain for integrity verification. */
2524
+ readonly chain_hash: string;
2525
+ }
2526
+ /** Input required to build a liability attribution record. */
2527
+ interface LiabilityAttributionInput {
2528
+ readonly execution_id: string;
2529
+ readonly org_id: string;
2530
+ readonly classification: LiabilityClassification;
2531
+ readonly risk_tier: FinancialRiskTier;
2532
+ readonly authorizer: Omit<LiabilityParty, "role" | "liability_weight">;
2533
+ readonly executor: Omit<LiabilityParty, "role" | "liability_weight">;
2534
+ readonly approvers: readonly Omit<LiabilityParty, "role" | "liability_weight">[];
2535
+ readonly delegations?: readonly {
2536
+ readonly delegator_id: string;
2537
+ readonly delegate_id: string;
2538
+ readonly delegator_label: string;
2539
+ readonly delegate_label: string;
2540
+ readonly delegator_type: "human" | "agent" | "system";
2541
+ readonly delegate_type: "human" | "agent" | "system";
2542
+ readonly permit_id: string | null;
2543
+ readonly acted_at: string;
2544
+ }[];
2545
+ readonly supervisors?: readonly Omit<LiabilityParty, "role" | "liability_weight">[];
2546
+ readonly override?: {
2547
+ readonly actor_id: string;
2548
+ readonly actor_label: string;
2549
+ readonly actor_type: "human" | "agent" | "system";
2550
+ readonly justification: string;
2551
+ readonly permit_id: string | null;
2552
+ readonly acted_at: string;
2553
+ };
2554
+ }
2555
+ /** Weight distribution strategy. */
2556
+ type WeightDistribution = "equal" | "role_weighted";
2557
+ /**
2558
+ * Compute liability weights for all parties in a chain.
2559
+ * Normalizes weights to sum to 1.0.
2560
+ */
2561
+ declare function computeLiabilityWeights(parties: readonly {
2562
+ role: LiabilityPartyRole;
2563
+ }[], distribution?: WeightDistribution): number[];
2564
+ /**
2565
+ * Build a liability chain from attribution input.
2566
+ * Assigns roles and computes normalized weights for each party.
2567
+ */
2568
+ declare function buildLiabilityChain(input: LiabilityAttributionInput, distribution?: WeightDistribution): LiabilityParty[];
2569
+ /**
2570
+ * Find all parties bearing primary liability (weight >= threshold).
2571
+ * Used in dispute workflows and regulatory reporting.
2572
+ */
2573
+ declare function findPrimaryLiabilityParties(chain: readonly LiabilityParty[], threshold?: number): LiabilityParty[];
2574
+ /** Result of validating a liability chain. */
2575
+ interface LiabilityChainValidation {
2576
+ readonly valid: boolean;
2577
+ readonly errors: readonly string[];
2578
+ }
2579
+ /**
2580
+ * Validate structural correctness of a liability chain:
2581
+ * - At least one party present
2582
+ * - Weights sum to ~1.0
2583
+ * - No duplicate party_id+role pairs
2584
+ * - override_actor present when hasEmergencyOverride is true
2585
+ */
2586
+ declare function validateLiabilityChain(chain: readonly LiabilityParty[], hasEmergencyOverride: boolean): LiabilityChainValidation;
2587
+
2588
+ /**
2589
+ * Economic Risk Engine.
2590
+ *
2591
+ * Computes financial exposure, approval concentration risk, override
2592
+ * frequency risk, budgetary drift, and execution anomaly risk for an
2593
+ * organization's financial governance posture.
2594
+ *
2595
+ * All computation is pure (no I/O). Inputs are derived from the
2596
+ * financial_execution_records and liability_attribution_records tables.
2597
+ *
2598
+ * Wire-stable as `economic_risk.v1`.
2599
+ */
2600
+
2601
+ /** Aggregate financial risk score for an organization or scope. */
2602
+ interface FinancialRiskScore {
2603
+ readonly scope_id: string;
2604
+ /** Overall risk score (0–100; higher = riskier). */
2605
+ readonly overall_score: number;
2606
+ readonly exposure_score: number;
2607
+ readonly concentration_score: number;
2608
+ readonly override_score: number;
2609
+ readonly drift_score: number;
2610
+ readonly anomaly_score: number;
2611
+ readonly implied_tier: FinancialRiskTier;
2612
+ readonly computed_at: string;
2613
+ readonly factors: readonly RiskFactor[];
2614
+ }
2615
+ /** A single contributing risk factor. */
2616
+ interface RiskFactor {
2617
+ readonly name: string;
2618
+ readonly score: number;
2619
+ readonly weight: number;
2620
+ readonly description: string;
2621
+ readonly evidence?: readonly string[];
2622
+ }
2623
+ /** Alert raised when approval authority is too concentrated. */
2624
+ interface ConcentrationAlert {
2625
+ readonly approver_id: string;
2626
+ /** Percentage of total approvals (0–100). */
2627
+ readonly approval_share_pct: number;
2628
+ readonly total_value_approved: number;
2629
+ readonly approval_count: number;
2630
+ readonly severity: "warn" | "critical";
2631
+ readonly window_start: string;
2632
+ readonly window_end: string;
2633
+ }
2634
+ /** Per-approver breakdown within a concentration analysis. */
2635
+ interface ApproverBreakdown {
2636
+ readonly approver_id: string;
2637
+ readonly approval_count: number;
2638
+ readonly total_value: number;
2639
+ /** Share as a percentage (0–100). */
2640
+ readonly share_pct: number;
2641
+ }
2642
+ /** Result of approval concentration analysis. */
2643
+ interface ApprovalConcentrationAnalysis {
2644
+ readonly scope_id: string;
2645
+ readonly analysis_window_days: number;
2646
+ readonly total_approvals: number;
2647
+ readonly total_value: number;
2648
+ readonly approver_breakdown: readonly ApproverBreakdown[];
2649
+ readonly alerts: readonly ConcentrationAlert[];
2650
+ /** Herfindahl-Hirschman Index (0–10000). */
2651
+ readonly concentration_hhi: number;
2652
+ readonly computed_at: string;
2653
+ }
2654
+ /** Budgetary drift analysis for a scope/period. */
2655
+ interface BudgetaryDriftAnalysis {
2656
+ readonly scope_id: string;
2657
+ readonly department_id: string | null;
2658
+ readonly period_start: string;
2659
+ readonly period_end: string;
2660
+ readonly budgeted_amount: number;
2661
+ readonly actual_amount: number;
2662
+ readonly variance_amount: number;
2663
+ readonly variance_pct: number;
2664
+ readonly drift_detected: boolean;
2665
+ readonly drift_severity: "none" | "minor" | "moderate" | "severe";
2666
+ readonly override_contribution_pct: number;
2667
+ readonly unauthorized_escalation_detected: boolean;
2668
+ }
2669
+ /** A single execution anomaly signal. */
2670
+ interface ExecutionAnomaly {
2671
+ readonly anomaly_id: string;
2672
+ readonly execution_id: string;
2673
+ readonly anomaly_type: AnomalyType;
2674
+ readonly description: string;
2675
+ readonly severity: "low" | "medium" | "high";
2676
+ readonly detected_at: string;
2677
+ readonly evidence: Record<string, unknown>;
2678
+ }
2679
+ /** Known anomaly types detected by the risk engine. */
2680
+ type AnomalyType = "unusual_amount" | "unusual_frequency" | "off_hours_execution" | "rapid_sequential" | "self_approval" | "jurisdiction_mismatch" | "dormant_approver" | "velocity_spike" | string;
2681
+ /**
2682
+ * Compute the overall financial risk score from sub-scores.
2683
+ * Returns a value in [0, 100].
2684
+ */
2685
+ declare function computeOverallRiskScore(subScores: {
2686
+ exposure: number;
2687
+ concentration: number;
2688
+ override: number;
2689
+ drift: number;
2690
+ anomaly: number;
2691
+ }): number;
2692
+ /**
2693
+ * Infer a risk tier from an overall score.
2694
+ * 0–25: low | 26–55: medium | 56–80: high | 81–100: critical
2695
+ */
2696
+ declare function scoreToRiskTier(score: number): FinancialRiskTier;
2697
+ /**
2698
+ * Compute the Herfindahl-Hirschman Index from a list of shares (0–100 each).
2699
+ * HHI > 2500 indicates high concentration.
2700
+ */
2701
+ declare function computeHHI(shares: readonly number[]): number;
2702
+ /** Map HHI (0–10000) to a concentration score (0–100). */
2703
+ declare function hhiToConcentrationScore(hhi: number): number;
2704
+ /**
2705
+ * Compute an exposure score (0–100) from execution records.
2706
+ * Total active-state value as a fraction of a reference ceiling.
2707
+ */
2708
+ declare function computeExposureScore(records: readonly Pick<FinancialExecutionRecord, "action_value" | "status" | "risk_tier">[], exposureCeilingUSD?: number): number;
2709
+ /**
2710
+ * Compute an override frequency score (0–100).
2711
+ * More than 10% override rate → score = 100.
2712
+ */
2713
+ declare function computeOverrideScore(totalExecutions: number, overriddenExecutions: number): number;
2714
+ /**
2715
+ * Detect self-approval: initiator and approver are the same party.
2716
+ */
2717
+ declare function detectSelfApproval(initiatorId: string, approverIds: readonly string[]): boolean;
2718
+ /** Compute an approval risk score from concentration analysis. */
2719
+ declare function computeApprovalRiskScore(analysis: ApprovalConcentrationAnalysis): number;
2720
+
2721
+ /**
2722
+ * Financial Quorum — extends the AtlaSent approval quorum model with
2723
+ * monetary thresholds, dynamic escalation, and emergency freeze support.
2724
+ *
2725
+ * Builds on the base QuorumPolicy in approvalQuorum.ts. Every financial
2726
+ * quorum check MUST first satisfy base quorum requirements before
2727
+ * financial-layer policy is evaluated.
2728
+ *
2729
+ * Wire-stable as `financial_quorum.v1`.
2730
+ */
2731
+
2732
+ /** A financial role requirement with optional monetary and tier filters. */
2733
+ interface FinancialRoleRequirement {
2734
+ readonly role: string;
2735
+ readonly min: number;
2736
+ /** Only apply this requirement when action value >= this amount. */
2737
+ readonly applies_above?: number;
2738
+ /** Only apply when the action's risk_tier is in this set. */
2739
+ readonly applies_to_tiers?: readonly FinancialRiskTier[];
2740
+ }
2741
+ /** Amount-based threshold that triggers additional quorum requirements. */
2742
+ interface AmountThreshold {
2743
+ readonly value: number;
2744
+ readonly currency: CurrencyCode;
2745
+ readonly additional_approvals: number;
2746
+ readonly additional_roles: readonly FinancialRoleRequirement[];
2747
+ readonly senior_review_required: boolean;
2748
+ }
2749
+ /**
2750
+ * Financial quorum policy.
2751
+ *
2752
+ * Extends the base QuorumPolicy with amount thresholds, financial role
2753
+ * requirements, regulator approval thresholds, and emergency freeze.
2754
+ */
2755
+ interface FinancialQuorumPolicy extends QuorumPolicy {
2756
+ readonly financial_role_requirements: readonly FinancialRoleRequirement[];
2757
+ readonly amount_thresholds: readonly AmountThreshold[];
2758
+ readonly reference_currency: CurrencyCode;
2759
+ readonly emergency_freeze_active: boolean;
2760
+ /** Regulator approval required above this value (null = not required). */
2761
+ readonly regulator_approval_threshold: number | null;
2762
+ /** Customer + vendor dual-release required above this value. */
2763
+ readonly dual_release_threshold: number | null;
2764
+ }
2765
+ /** Emergency freeze record — applied org-wide or per scope. */
2766
+ interface EmergencyFreeze {
2767
+ readonly freeze_id: string;
2768
+ readonly scope_id: string;
2769
+ readonly scope_type: "org" | "department" | "action_class";
2770
+ readonly triggered_by: string;
2771
+ readonly reason: string;
2772
+ readonly triggered_at: string;
2773
+ readonly expires_at: string | null;
2774
+ readonly lifted: boolean;
2775
+ readonly lifted_at: string | null;
2776
+ readonly lifted_by: string | null;
2777
+ }
2778
+ /** Result of evaluating a financial quorum. */
2779
+ interface FinancialQuorumResult {
2780
+ readonly passed: boolean;
2781
+ readonly base_quorum_passed: boolean;
2782
+ readonly amount_threshold_satisfied: boolean;
2783
+ readonly financial_roles_satisfied: boolean;
2784
+ readonly regulator_approval_missing: boolean;
2785
+ readonly blocked_by_freeze: boolean;
2786
+ readonly base_quorum_proof: QuorumProof | null;
2787
+ readonly denial_reason: string | null;
2788
+ readonly unmet_requirements: readonly string[];
2789
+ }
2790
+ /** Input to financial quorum evaluation. */
2791
+ interface FinancialQuorumInput {
2792
+ readonly policy: FinancialQuorumPolicy;
2793
+ readonly action_value: number;
2794
+ readonly risk_tier: FinancialRiskTier;
2795
+ /** Roles present in the approval set (role → count). */
2796
+ readonly present_roles: Record<string, number>;
2797
+ readonly approval_count: number;
2798
+ readonly regulator_approval_present: boolean;
2799
+ readonly base_quorum_proof: QuorumProof | null;
2800
+ readonly active_freezes: readonly EmergencyFreeze[];
2801
+ }
2802
+ /**
2803
+ * Evaluate a financial quorum policy.
2804
+ *
2805
+ * Checks in order: emergency freeze → base count → amount thresholds
2806
+ * → financial roles → regulator approval.
2807
+ */
2808
+ declare function evaluateFinancialQuorum(input: FinancialQuorumInput): FinancialQuorumResult;
2809
+ /**
2810
+ * Determine the escalated minimum approval count for a given action value.
2811
+ * Returns base count plus the largest additional_approvals from matching thresholds.
2812
+ */
2813
+ declare function computeEscalatedApprovalCount(baseCount: number, actionValue: number, thresholds: readonly AmountThreshold[]): number;
2814
+
2815
+ /**
2816
+ * Budgetary Governance — policy and constraint infrastructure for
2817
+ * organizational financial limits.
2818
+ *
2819
+ * Prevents budget overruns, unauthorized escalations, and hidden approvals
2820
+ * by enforcing declared spending constraints before financial actions
2821
+ * are authorized.
2822
+ *
2823
+ * Wire-stable as `budget_governance.v1`.
2824
+ */
2825
+
2826
+ /** Scope a budget limit applies to. */
2827
+ type BudgetScope = "org" | "department" | "team" | "environment" | "action_class" | "project" | "time_bounded";
2828
+ /** A declared budget limit for a scope. */
2829
+ interface BudgetLimit {
2830
+ readonly limit_id: string;
2831
+ readonly org_id: string;
2832
+ readonly scope_type: BudgetScope;
2833
+ readonly scope_id: string;
2834
+ readonly limit_amount: number;
2835
+ readonly currency: CurrencyCode;
2836
+ /** Hard limits block execution; soft limits warn only. */
2837
+ readonly enforcement: "hard" | "soft";
2838
+ readonly period_start: string | null;
2839
+ readonly period_end: string | null;
2840
+ readonly active: boolean;
2841
+ readonly created_by: string;
2842
+ readonly created_at: string;
2843
+ }
2844
+ /** Current spending state against a budget limit. */
2845
+ interface BudgetSpendingState {
2846
+ readonly limit_id: string;
2847
+ readonly spent_amount: number;
2848
+ readonly remaining_amount: number;
2849
+ readonly exceeded: boolean;
2850
+ /** Utilization percentage (0–100+). */
2851
+ readonly utilization_pct: number;
2852
+ readonly updated_at: string;
2853
+ }
2854
+ /** A spending constraint on a financial action class or type. */
2855
+ interface SpendingConstraint {
2856
+ readonly constraint_id: string;
2857
+ readonly org_id: string;
2858
+ /** "*" matches all action types. */
2859
+ readonly action_type: FinancialActionType | "*";
2860
+ readonly max_single_transaction: number;
2861
+ readonly max_daily_aggregate: number | null;
2862
+ readonly max_monthly_aggregate: number | null;
2863
+ readonly currency: CurrencyCode;
2864
+ readonly applies_to_tier_gte: FinancialRiskTier | null;
2865
+ readonly allow_anonymous_agents: boolean;
2866
+ readonly active: boolean;
2867
+ }
2868
+ /** A specific budget violation. */
2869
+ interface BudgetViolation {
2870
+ readonly violation_type: "limit_exceeded" | "single_transaction_exceeds" | "daily_aggregate_exceeds" | "monthly_aggregate_exceeds" | "anonymous_agent_blocked" | "period_expired";
2871
+ readonly limit_id?: string;
2872
+ readonly constraint_id?: string;
2873
+ readonly description: string;
2874
+ readonly overage_amount?: number;
2875
+ }
2876
+ /** Result of checking an action against budget constraints. */
2877
+ interface BudgetConstraintCheckResult {
2878
+ readonly permitted: boolean;
2879
+ readonly hard_blocks: readonly BudgetViolation[];
2880
+ readonly soft_warnings: readonly BudgetViolation[];
2881
+ readonly limits_checked: readonly string[];
2882
+ readonly constraints_checked: readonly string[];
2883
+ }
2884
+ /** A complete budget policy document for an organization. */
2885
+ interface BudgetPolicy {
2886
+ readonly policy_id: string;
2887
+ readonly org_id: string;
2888
+ readonly name: string;
2889
+ readonly limits: readonly BudgetLimit[];
2890
+ readonly constraints: readonly SpendingConstraint[];
2891
+ readonly override_requires_exception: boolean;
2892
+ readonly allow_approved_escalation: boolean;
2893
+ readonly version: string;
2894
+ readonly effective_from: string;
2895
+ readonly expires_at: string | null;
2896
+ }
2897
+ /**
2898
+ * Check an action value against applicable budget limits and constraints.
2899
+ *
2900
+ * Hard limits block execution; soft limits surface as warnings.
2901
+ */
2902
+ declare function checkBudgetConstraints(params: {
2903
+ actionValue: number;
2904
+ currency: CurrencyCode;
2905
+ actionType: FinancialActionType;
2906
+ riskTier: FinancialRiskTier;
2907
+ isAnonymousAgent: boolean;
2908
+ currentDailySpend: number;
2909
+ currentMonthlySpend: number;
2910
+ applicableLimits: readonly (BudgetLimit & {
2911
+ spending: BudgetSpendingState;
2912
+ })[];
2913
+ applicableConstraints: readonly SpendingConstraint[];
2914
+ now?: Date;
2915
+ }): BudgetConstraintCheckResult;
2916
+ /**
2917
+ * Determine budget utilization severity for dashboard display.
2918
+ */
2919
+ declare function budgetUtilizationSeverity(utilizationPct: number): "normal" | "warn" | "critical";
2920
+
2921
+ /**
2922
+ * Autonomous Financial Execution — governance for AI-driven financial actions.
2923
+ *
2924
+ * Defines bounded authority, execution ceilings, and runtime verification
2925
+ * requirements for autonomous agents performing financial operations:
2926
+ * refunds, procurement, cloud-cost optimization, vendor payments, etc.
2927
+ *
2928
+ * Wire-stable as `autonomous_financial.v1`.
2929
+ */
2930
+
2931
+ /** Authority bounds for an autonomous financial agent. */
2932
+ interface AutonomousExecutionBounds {
2933
+ readonly bounds_id: string;
2934
+ readonly org_id: string;
2935
+ readonly agent_id: string;
2936
+ readonly agent_name: string;
2937
+ /** Action types this agent is permitted to execute autonomously. */
2938
+ readonly permitted_action_types: readonly FinancialActionType[];
2939
+ readonly ceilings: readonly ExecutionCeiling[];
2940
+ readonly daily_aggregate_ceiling: number;
2941
+ readonly aggregate_currency: CurrencyCode;
2942
+ /** Maximum risk tier the agent may autonomously execute. */
2943
+ readonly max_risk_tier: FinancialRiskTier;
2944
+ readonly require_runtime_verification: boolean;
2945
+ readonly anomaly_detection_enabled: boolean;
2946
+ readonly created_at: string;
2947
+ readonly expires_at: string | null;
2948
+ readonly active: boolean;
2949
+ }
2950
+ /** Per-action-type execution ceiling. */
2951
+ interface ExecutionCeiling {
2952
+ readonly action_type: FinancialActionType;
2953
+ readonly per_execution_max: number;
2954
+ readonly currency: CurrencyCode;
2955
+ readonly max_daily_count: number | null;
2956
+ readonly require_permit: boolean;
2957
+ }
2958
+ /** Record of an autonomous execution attempt. */
2959
+ interface AutonomousExecutionRecord {
2960
+ readonly record_id: string;
2961
+ readonly agent_id: string;
2962
+ readonly org_id: string;
2963
+ readonly action_type: FinancialActionType;
2964
+ readonly action_value: number;
2965
+ readonly currency: CurrencyCode;
2966
+ readonly permitted: boolean;
2967
+ readonly denial_reason: string | null;
2968
+ readonly permit_id: string | null;
2969
+ readonly anomaly_detected: boolean;
2970
+ readonly anomaly_description: string | null;
2971
+ readonly attempted_at: string;
2972
+ readonly executed_at: string | null;
2973
+ }
2974
+ /** Result of checking whether an autonomous execution is within bounds. */
2975
+ interface AutonomousExecutionCheckResult {
2976
+ readonly permitted: boolean;
2977
+ readonly action_type_permitted: boolean;
2978
+ readonly within_execution_ceiling: boolean;
2979
+ readonly within_daily_aggregate: boolean;
2980
+ readonly within_risk_tier: boolean;
2981
+ readonly bounds_active: boolean;
2982
+ readonly bounds_not_expired: boolean;
2983
+ readonly applicable_ceiling: ExecutionCeiling | null;
2984
+ readonly denial_reason: string | null;
2985
+ readonly violations: readonly string[];
2986
+ }
2987
+ /**
2988
+ * Check whether an autonomous execution is within declared bounds.
2989
+ */
2990
+ declare function checkAutonomousBounds(params: {
2991
+ bounds: AutonomousExecutionBounds;
2992
+ actionType: FinancialActionType;
2993
+ actionValue: number;
2994
+ currency: CurrencyCode;
2995
+ riskTier: FinancialRiskTier;
2996
+ currentDailyAggregate: number;
2997
+ currentDailyCount: Partial<Record<string, number>>;
2998
+ now?: Date;
2999
+ }): AutonomousExecutionCheckResult;
3000
+ /**
3001
+ * Detect a potential anomaly in autonomous execution.
3002
+ * Returns a description when an anomaly is detected, or null.
3003
+ */
3004
+ declare function detectAutonomousAnomaly(params: {
3005
+ actionValue: number;
3006
+ historicalMeanValue: number;
3007
+ historicalStdDev: number;
3008
+ recentExecutionCount: number;
3009
+ burstThreshold: number;
3010
+ isOffHours: boolean;
3011
+ }): {
3012
+ anomalyDetected: boolean;
3013
+ description: string | null;
3014
+ };
3015
+
3016
+ /**
3017
+ * Incentive Alignment Engine.
3018
+ *
3019
+ * Detects governance anti-patterns that indicate misaligned incentives:
3020
+ * excessive overrides, rushed approvals, emergency bypass repetition,
3021
+ * authority concentration, and governance fatigue.
3022
+ *
3023
+ * These signals are leading indicators of systemic governance failure.
3024
+ * They do not block execution but feed into risk scoring and dashboards.
3025
+ *
3026
+ * Wire-stable as `incentive_alignment.v1`.
3027
+ */
3028
+ /** Categories of governance incentive signals. */
3029
+ type IncentiveSignalType = "excessive_overrides" | "rushed_approval" | "emergency_bypass_repeat" | "authority_concentration" | "rubber_stamping" | "approval_collusion" | "escalation_avoidance" | "governance_fatigue" | "delegation_chain_depth" | "approval_velocity_spike";
3030
+ /** A detected incentive alignment signal. */
3031
+ interface IncentiveSignal {
3032
+ readonly signal_id: string;
3033
+ readonly signal_type: IncentiveSignalType;
3034
+ readonly party_id: string;
3035
+ readonly party_label: string;
3036
+ /** Severity (0–100). */
3037
+ readonly severity: number;
3038
+ readonly description: string;
3039
+ readonly evidence: readonly string[];
3040
+ readonly detected_at: string;
3041
+ readonly reviewed: boolean;
3042
+ readonly reviewed_by: string | null;
3043
+ }
3044
+ /** Behavior pattern analysis for a governance actor. */
3045
+ interface GovernanceBehaviorPattern {
3046
+ readonly party_id: string;
3047
+ readonly party_label: string;
3048
+ readonly observation_window_days: number;
3049
+ readonly total_approvals: number;
3050
+ readonly total_overrides: number;
3051
+ readonly total_emergency_bypasses: number;
3052
+ readonly mean_approval_latency_seconds: number;
3053
+ readonly min_approval_latency_seconds: number;
3054
+ readonly approval_concentration_score: number;
3055
+ readonly delegation_depth_max: number;
3056
+ readonly signals: readonly IncentiveSignal[];
3057
+ /** 0–100; higher = healthier governance posture. */
3058
+ readonly governance_health_score: number;
3059
+ }
3060
+ /** Misalignment alert for operator review. */
3061
+ interface MisalignmentAlert {
3062
+ readonly alert_id: string;
3063
+ readonly org_id: string;
3064
+ readonly severity: "warn" | "critical";
3065
+ readonly alert_type: IncentiveSignalType;
3066
+ readonly affected_party_ids: readonly string[];
3067
+ readonly description: string;
3068
+ readonly recommendation: string;
3069
+ readonly signals: readonly IncentiveSignal[];
3070
+ readonly created_at: string;
3071
+ readonly resolved: boolean;
3072
+ readonly resolved_at: string | null;
3073
+ }
3074
+ /** Thresholds for incentive alignment detection. */
3075
+ interface IncentiveAlignmentConfig {
3076
+ readonly max_override_rate: number;
3077
+ readonly min_approval_latency_seconds: number;
3078
+ readonly max_emergency_bypasses_30d: number;
3079
+ readonly max_concentration_share: number;
3080
+ readonly max_delegation_depth: number;
3081
+ }
3082
+ declare const DEFAULT_INCENTIVE_CONFIG: IncentiveAlignmentConfig;
3083
+ /**
3084
+ * Analyze a governance actor's behavior to detect misaligned incentives.
3085
+ * Returns signals sorted by severity (highest first).
3086
+ */
3087
+ declare function detectMisalignedIncentives(params: {
3088
+ partyId: string;
3089
+ partyLabel: string;
3090
+ windowDays: number;
3091
+ totalActions: number;
3092
+ overrideCount: number;
3093
+ emergencyBypassCount: number;
3094
+ approvalLatencies: readonly number[];
3095
+ approvalShare: number;
3096
+ delegationDepthMax: number;
3097
+ config?: IncentiveAlignmentConfig;
3098
+ now?: Date;
3099
+ }): IncentiveSignal[];
3100
+ /**
3101
+ * Compute a governance health score (0–100).
3102
+ * 100 = perfect governance; 0 = extreme misalignment.
3103
+ */
3104
+ declare function computeGovernanceHealthScore(signals: readonly IncentiveSignal[]): number;
3105
+
3106
+ /**
3107
+ * Economic Evidence Bundles.
3108
+ *
3109
+ * Generates signed evidence proving approval provenance, execution
3110
+ * authorization, runtime conformity, liability chain, and policy compliance
3111
+ * for regulatory review, insurance, financial audit, and legal discovery.
3112
+ *
3113
+ * Follows the same signing pattern as auditBundle.ts, scoped to financial
3114
+ * governance evidence.
3115
+ *
3116
+ * Wire-stable as `economic_evidence.v1`.
3117
+ */
3118
+
3119
+ /** Purpose for which an economic evidence bundle is generated. */
3120
+ type EvidencePurpose = "regulator_review" | "insurance_review" | "financial_audit" | "legal_discovery" | "internal_review" | "dispute_resolution";
3121
+ /** Approval provenance record within the evidence bundle. */
3122
+ interface ApprovalProvenance {
3123
+ readonly approver_id: string;
3124
+ readonly approver_label: string;
3125
+ readonly permit_id: string;
3126
+ readonly approved_at: string;
3127
+ readonly audit_hash: string;
3128
+ readonly role: string;
3129
+ }
3130
+ /** Complete economic evidence bundle. */
3131
+ interface EconomicEvidenceBundle {
3132
+ readonly version: "economic_evidence.v1";
3133
+ readonly bundle_id: string;
3134
+ readonly org_id: string;
3135
+ readonly purpose: EvidencePurpose;
3136
+ readonly execution_record: FinancialExecutionRecord;
3137
+ readonly liability_attribution: LiabilityAttributionRecord;
3138
+ readonly quorum_result: FinancialQuorumResult;
3139
+ readonly budget_check: BudgetConstraintCheckResult;
3140
+ readonly approval_provenance: readonly ApprovalProvenance[];
3141
+ readonly runtime_conformity: boolean;
3142
+ readonly runtime_conformity_notes: readonly string[];
3143
+ readonly policy_compliant: boolean;
3144
+ readonly policy_violations: readonly string[];
3145
+ readonly generated_at: string;
3146
+ readonly requested_by: string;
3147
+ /** SHA-256 hex of the canonical signable content. */
3148
+ readonly content_hash: string;
3149
+ /** Base64url Ed25519 signature of the canonical content. */
3150
+ readonly signature: string | null;
3151
+ readonly signing_key_id: string | null;
3152
+ }
3153
+ /** Canonical content shape that gets hashed and signed. */
3154
+ interface EvidenceBundleSignableContent {
3155
+ readonly bundle_id: string;
3156
+ readonly org_id: string;
3157
+ readonly purpose: EvidencePurpose;
3158
+ readonly execution_id: string;
3159
+ readonly attribution_id: string;
3160
+ readonly liability_chain_hash: string;
3161
+ readonly approval_count: number;
3162
+ readonly permit_ids: readonly string[];
3163
+ readonly policy_compliant: boolean;
3164
+ readonly generated_at: string;
3165
+ }
3166
+ /** Verification result for an economic evidence bundle. */
3167
+ interface EvidenceBundleVerificationResult {
3168
+ readonly valid: boolean;
3169
+ readonly content_hash_valid: boolean;
3170
+ readonly signature_valid: boolean;
3171
+ readonly liability_chain_hash_matches: boolean;
3172
+ readonly permit_ids_match: boolean;
3173
+ readonly reason: string | null;
3174
+ }
3175
+ /**
3176
+ * Canonicalize a value to a stable string representation.
3177
+ *
3178
+ * Exported (rather than file-private) to enable cross-language
3179
+ * byte-equivalence verification against the Python implementation in
3180
+ * ``atlasent-sdk/python/atlasent/governance/_canonical.py``. The shared
3181
+ * fixture lives at ``compat/governance/fixtures/parity.json``.
3182
+ */
3183
+ declare function canonicalizeForEvidence(value: unknown): string;
3184
+ /**
3185
+ * Build the signable content object for a bundle.
3186
+ * Key order is load-bearing — must remain stable across versions.
3187
+ */
3188
+ declare function buildSignableContent(bundle: Omit<EconomicEvidenceBundle, "content_hash" | "signature" | "signing_key_id">): EvidenceBundleSignableContent;
3189
+ /**
3190
+ * Serialize signable content to canonical UTF-8 bytes.
3191
+ * Uses the same sort-keyed canonicalization as auditBundle.
3192
+ */
3193
+ declare function serializeSignableContent(content: EvidenceBundleSignableContent): Uint8Array;
3194
+ /**
3195
+ * Verify an economic evidence bundle's structural integrity.
3196
+ * Does NOT verify the Ed25519 signature (requires crypto keys).
3197
+ */
3198
+ declare function verifyEvidenceBundleStructure(bundle: EconomicEvidenceBundle): EvidenceBundleVerificationResult;
3199
+
3200
+ /**
3201
+ * Dispute + Reversal Workflows.
3202
+ *
3203
+ * Manages disputed financial actions, rollback workflows, frozen actions,
3204
+ * and temporary suspensions. Tracks dispute origin, remediation timeline,
3205
+ * and reversal authority.
3206
+ *
3207
+ * Wire-stable as `dispute_reversal.v1`.
3208
+ */
3209
+
3210
+ /** Who or what originated a dispute. */
3211
+ type DisputeOrigin = "counterparty" | "regulator" | "internal_audit" | "fraud_detection" | "approver_retract" | "policy_violation" | "agent_error";
3212
+ /** Current state of a dispute. */
3213
+ type DisputeStatus = "open" | "under_review" | "escalated" | "resolved_in_favor" | "resolved_against" | "reversed" | "withdrawn";
3214
+ /** A dispute record for a financial action. */
3215
+ interface DisputeRecord {
3216
+ readonly dispute_id: string;
3217
+ readonly execution_id: string;
3218
+ readonly org_id: string;
3219
+ readonly origin: DisputeOrigin;
3220
+ readonly filed_by: string;
3221
+ readonly description: string;
3222
+ readonly status: DisputeStatus;
3223
+ readonly execution_frozen: boolean;
3224
+ readonly opened_at: string;
3225
+ readonly resolution_deadline: string | null;
3226
+ readonly resolved_at: string | null;
3227
+ readonly resolved_by: string | null;
3228
+ readonly resolution_notes: string | null;
3229
+ readonly reversal_initiated: boolean;
3230
+ readonly reversal_id: string | null;
3231
+ }
3232
+ /** Reversal workflow stage. */
3233
+ type ReversalStage = "initiated" | "authorization_pending" | "authorized" | "executing" | "completed" | "failed" | "cancelled";
3234
+ /** A reversal workflow for a financial execution. */
3235
+ interface ReversalWorkflow {
3236
+ readonly reversal_id: string;
3237
+ readonly execution_id: string;
3238
+ readonly dispute_id: string | null;
3239
+ readonly org_id: string;
3240
+ readonly initiated_by: string;
3241
+ readonly reason: string;
3242
+ readonly stage: ReversalStage;
3243
+ readonly authorized_by: string | null;
3244
+ readonly authorization_permit_id: string | null;
3245
+ readonly initiated_at: string;
3246
+ readonly authorized_at: string | null;
3247
+ readonly completed_at: string | null;
3248
+ readonly reversal_value: number;
3249
+ readonly partial: boolean;
3250
+ }
3251
+ /** Action freeze record. */
3252
+ interface ActionFreeze {
3253
+ readonly freeze_id: string;
3254
+ readonly execution_id: string;
3255
+ readonly org_id: string;
3256
+ readonly triggered_by: string;
3257
+ readonly reason: string;
3258
+ readonly triggered_at: string;
3259
+ readonly expires_at: string | null;
3260
+ readonly lifted: boolean;
3261
+ readonly lifted_at: string | null;
3262
+ readonly lifted_by: string | null;
3263
+ readonly frozen_status: FinancialExecutionStatus;
3264
+ }
3265
+ /** Validate and apply a dispute status transition. */
3266
+ declare function transitionDispute(current: DisputeStatus, next: DisputeStatus): {
3267
+ success: boolean;
3268
+ new_status: DisputeStatus | null;
3269
+ error: string | null;
3270
+ };
3271
+ /** Validate and apply a reversal workflow stage transition. */
3272
+ declare function transitionReversal(current: ReversalStage, next: ReversalStage): {
3273
+ success: boolean;
3274
+ error: string | null;
3275
+ };
3276
+ /**
3277
+ * Return true when a freeze is currently active (not lifted and not expired).
3278
+ */
3279
+ declare function isFreezeActive(freeze: ActionFreeze, now?: Date): boolean;
3280
+ /**
3281
+ * Compute remediation urgency based on dispute deadline.
3282
+ * Returns 'overdue' when past deadline, 'urgent' within 24h, else 'normal'.
3283
+ */
3284
+ declare function computeRemediationUrgency(_openedAt: string, deadline: string | null, now?: Date): "normal" | "urgent" | "overdue";
3285
+
3286
+ /**
3287
+ * Financial Control Dashboard — types for governance visualization.
3288
+ *
3289
+ * Covers approval concentration analysis, override analytics, budget drift,
3290
+ * economic risk timelines, and liability visualization.
3291
+ *
3292
+ * These are pure data types; rendering is left to UI consumers.
3293
+ *
3294
+ * Wire-stable as `financial_dashboard.v1`.
3295
+ */
3296
+
3297
+ /** Top-level financial governance summary for a dashboard view. */
3298
+ interface FinancialGovernanceSummary {
3299
+ readonly org_id: string;
3300
+ readonly generated_at: string;
3301
+ readonly window_days: number;
3302
+ readonly current_risk_score: FinancialRiskScore;
3303
+ readonly total_actions: number;
3304
+ readonly total_value: number;
3305
+ readonly override_count: number;
3306
+ readonly emergency_bypass_count: number;
3307
+ readonly active_dispute_count: number;
3308
+ readonly pending_reversal_count: number;
3309
+ readonly active_freeze_count: number;
3310
+ readonly budget_warning_count: number;
3311
+ readonly budget_critical_count: number;
3312
+ readonly concentration_analysis: ApprovalConcentrationAnalysis;
3313
+ readonly budget_drift: readonly BudgetaryDriftAnalysis[];
3314
+ readonly misalignment_alerts: readonly MisalignmentAlert[];
3315
+ readonly risk_timeline: readonly RiskTimelinePoint[];
3316
+ }
3317
+ /** A single point on the economic risk timeline. */
3318
+ interface RiskTimelinePoint {
3319
+ readonly date: string;
3320
+ readonly risk_score: number;
3321
+ readonly risk_tier: FinancialRiskTier;
3322
+ readonly action_count: number;
3323
+ readonly total_value: number;
3324
+ readonly override_count: number;
3325
+ readonly anomaly_count: number;
3326
+ }
3327
+ /** Override analytics for operator review. */
3328
+ interface OverrideAnalytics {
3329
+ readonly org_id: string;
3330
+ readonly window_days: number;
3331
+ readonly total_overrides: number;
3332
+ readonly override_rate: number;
3333
+ readonly overrides_by_actor: readonly ActorOverrideStat[];
3334
+ readonly overrides_by_action_type: readonly ActionTypeOverrideStat[];
3335
+ readonly override_value_total: number;
3336
+ readonly repeat_override_actors: readonly string[];
3337
+ readonly emergency_override_count: number;
3338
+ readonly computed_at: string;
3339
+ }
3340
+ interface ActorOverrideStat {
3341
+ readonly actor_id: string;
3342
+ readonly actor_label: string;
3343
+ readonly override_count: number;
3344
+ readonly override_value_total: number;
3345
+ readonly last_override_at: string;
3346
+ }
3347
+ interface ActionTypeOverrideStat {
3348
+ readonly action_type: string;
3349
+ readonly override_count: number;
3350
+ readonly total_value: number;
3351
+ }
3352
+ /** Liability visualization data for graph/chart rendering. */
3353
+ interface LiabilityVisualization {
3354
+ readonly execution_id: string;
3355
+ readonly org_id: string;
3356
+ readonly nodes: readonly LiabilityNode[];
3357
+ readonly edges: readonly LiabilityEdge[];
3358
+ readonly total_weight: number;
3359
+ }
3360
+ interface LiabilityNode {
3361
+ readonly id: string;
3362
+ readonly label: string;
3363
+ readonly party_type: "human" | "agent" | "system";
3364
+ readonly role: string;
3365
+ readonly liability_weight: number;
3366
+ readonly acted_at: string;
3367
+ }
3368
+ interface LiabilityEdge {
3369
+ readonly from_id: string;
3370
+ readonly to_id: string;
3371
+ readonly relationship: "authorized" | "delegated_to" | "approved_for" | "supervised" | "overrode";
3372
+ readonly weight: number;
3373
+ }
3374
+ /** Active disputes and reversals dashboard summary. */
3375
+ interface DisputeReversalSummary {
3376
+ readonly org_id: string;
3377
+ readonly active_disputes: readonly DisputeRecord[];
3378
+ readonly pending_reversals: readonly ReversalWorkflow[];
3379
+ readonly resolved_last_30d: number;
3380
+ readonly average_resolution_days: number;
3381
+ readonly overdue_disputes: readonly DisputeRecord[];
3382
+ readonly total_disputed_value: number;
3383
+ readonly total_reversed_value: number;
3384
+ readonly generated_at: string;
3385
+ }
3386
+ /**
3387
+ * Build a liability visualization graph from a liability chain.
3388
+ */
3389
+ declare function buildLiabilityVisualization(executionId: string, orgId: string, chain: readonly LiabilityParty[]): LiabilityVisualization;
3390
+ /**
3391
+ * Build a risk timeline from daily snapshot data.
3392
+ */
3393
+ declare function buildRiskTimeline(snapshots: readonly {
3394
+ date: string;
3395
+ riskScore: number;
3396
+ actionCount: number;
3397
+ totalValue: number;
3398
+ overrideCount: number;
3399
+ anomalyCount: number;
3400
+ }[]): RiskTimelinePoint[];
3401
+
3402
+ /**
3403
+ * Enforcement-layer helpers for the canonical economic governance primitives.
3404
+ *
3405
+ * The canonical EGAS modules (`financialQuorum`, `liabilityAttribution`,
3406
+ * `economicEvidence`, `budgetaryGovernance`, `autonomousFinancial`) are
3407
+ * **advisory**: they produce structured decision objects but never block
3408
+ * execution. This module converts "not permitted" advisory results into
3409
+ * thrown {@link GovernanceEnforcementError} so callers cannot silently
3410
+ * proceed when a governance gate refuses an action.
3411
+ *
3412
+ * Three gates, layered in this order at consumer call sites:
3413
+ *
3414
+ * ```ts
3415
+ * enforceFinancialQuorum(quorumResult);
3416
+ * enforceBudgetConstraint(budgetResult);
3417
+ * enforceAutonomousBounds(autonomousResult);
3418
+ * ```
3419
+ *
3420
+ * Each helper is a no-op when its result is permitted; otherwise it throws
3421
+ * with a stable {@link GovernanceEnforcementError.denyCode} matching a row
3422
+ * in `docs/APPROVAL_DENY_REASONS.md`. The deny-code taxonomy is locked
3423
+ * cross-language by the parity fixture at
3424
+ * `compat/governance/fixtures/parity.json`.
3425
+ */
3426
+
3427
+ /** Which enforcement gate fired. */
3428
+ type GovernanceGate = "financial_quorum" | "budget" | "autonomous_bounds";
3429
+ /** Stable deny codes for the financial-quorum gate. */
3430
+ type FinancialQuorumDenyCode = "blocked_by_emergency_freeze" | "base_count_unmet" | "amount_threshold_unmet" | "financial_role_unmet" | "regulator_approval_missing";
3431
+ /** Stable deny codes for the budget gate. */
3432
+ type BudgetDenyCode = "limit_exceeded" | "single_transaction_exceeds" | "daily_aggregate_exceeds" | "monthly_aggregate_exceeds" | "anonymous_agent_blocked" | "period_expired";
3433
+ /** Stable deny codes for the autonomous-bounds gate. */
3434
+ type AutonomousBoundsDenyCode = "inactive" | "expired" | "action_type_not_permitted" | "execution_ceiling_exceeded" | "daily_aggregate_exceeded" | "risk_tier_exceeded";
3435
+ /** Initialization options for {@link GovernanceEnforcementError}. */
3436
+ interface GovernanceEnforcementErrorInit {
3437
+ gate: GovernanceGate;
3438
+ denyCode: string;
3439
+ reason: string;
3440
+ details: unknown;
3441
+ requestId?: string;
3442
+ }
3443
+ /**
3444
+ * Thrown when an EGAS advisory result fails an enforcement gate.
3445
+ *
3446
+ * Extends {@link AtlaSentError} so `instanceof AtlaSentError` catches
3447
+ * these too. Use `instanceof GovernanceEnforcementError` to distinguish
3448
+ * a governance refusal from a transport / config error.
3449
+ */
3450
+ declare class GovernanceEnforcementError extends AtlaSentError {
3451
+ name: string;
3452
+ /** Which gate fired (`financial_quorum` / `budget` / `autonomous_bounds`). */
3453
+ readonly gate: GovernanceGate;
3454
+ /** Stable taxonomy code; maps to a row in `docs/APPROVAL_DENY_REASONS.md`. */
3455
+ readonly denyCode: string;
3456
+ /** Human-readable explanation. Do NOT branch on this string — branch on `denyCode`. */
3457
+ readonly reason: string;
3458
+ /** The structured advisory result that produced the denial. */
3459
+ readonly details: unknown;
3460
+ constructor(init: GovernanceEnforcementErrorInit);
3461
+ /** Combined `<gate>/<denyCode>` string used in audit records. */
3462
+ get fullyQualifiedCode(): string;
3463
+ }
3464
+ /**
3465
+ * Throw {@link GovernanceEnforcementError} when a quorum result fails.
3466
+ * Returns silently when `result.passed` is true.
3467
+ */
3468
+ declare function enforceFinancialQuorum(result: FinancialQuorumResult): void;
3469
+ /**
3470
+ * Throw {@link GovernanceEnforcementError} on a budget hard block.
3471
+ *
3472
+ * Returns silently when `result.permitted` is true (no hard blocks; soft
3473
+ * warnings do not cause enforcement to fire).
3474
+ */
3475
+ declare function enforceBudgetConstraint(result: BudgetConstraintCheckResult): void;
3476
+ /**
3477
+ * Throw {@link GovernanceEnforcementError} when autonomous bounds fail.
3478
+ * Returns silently when `result.permitted` is true.
3479
+ */
3480
+ declare function enforceAutonomousBounds(result: AutonomousExecutionCheckResult): void;
3481
+ /**
3482
+ * Convenience: layer all three gates in canonical order.
3483
+ *
3484
+ * Order: quorum (who approved) → budget (does it fit policy spend) →
3485
+ * autonomous_bounds (is the agent allowed to do this autonomously). The
3486
+ * first failing gate throws; subsequent gates are not evaluated.
3487
+ *
3488
+ * Pass `undefined` for gates that don't apply (e.g. omit `autonomous` for
3489
+ * human-initiated actions).
3490
+ */
3491
+ declare function enforceEconomicGovernance(params: {
3492
+ quorum?: FinancialQuorumResult;
3493
+ budget?: BudgetConstraintCheckResult;
3494
+ autonomous?: AutonomousExecutionCheckResult;
3495
+ }): void;
3496
+
3497
+ /**
3498
+ * Governance and enforcement webhook types — wire shapes for
3499
+ * `v1-governance-webhooks` and `v1-enforcement-webhooks`.
3500
+ *
3501
+ * Covers subscription management, signed delivery callbacks, and
3502
+ * delivery receipt records. Use `verifyWebhookSignature` in your
3503
+ * receiver to authenticate payloads.
3504
+ */
3505
+ type GovernanceWebhookEvent = "enforcement.blocked" | "policy.violation" | "access_review.completed" | "mfa.enrollment_required" | "contract.activated" | "replay.drift_detected";
3506
+ type EnforcementWebhookEvent = "enforcement.blocked" | "enforcement.pending_approval" | "enforcement.approved" | "enforcement.expired";
3507
+ type WebhookDeliveryStatus = "pending" | "delivered" | "failed";
3508
+ interface WebhookSubscription {
3509
+ id: string;
3510
+ org_id: string;
3511
+ url: string;
3512
+ events: string[];
3513
+ enabled: boolean;
3514
+ description: string | null;
3515
+ created_at: string;
3516
+ }
3517
+ interface WebhookDelivery {
3518
+ id: string;
3519
+ subscription_id: string;
3520
+ event_type: string;
3521
+ payload: Record<string, unknown>;
3522
+ status: WebhookDeliveryStatus;
3523
+ response_status: number | null;
3524
+ response_body: string | null;
3525
+ attempted_at: string;
3526
+ }
3527
+ interface CreateWebhookSubscriptionRequest {
3528
+ url: string;
3529
+ events: string[];
3530
+ enabled?: boolean;
3531
+ description?: string;
3532
+ }
3533
+ interface ListWebhookSubscriptionsResponse {
3534
+ subscriptions: WebhookSubscription[];
3535
+ /** For governance webhooks, the server returns supported event names. */
3536
+ valid_events?: string[];
3537
+ }
3538
+ interface ListWebhookDeliveriesResponse {
3539
+ deliveries: WebhookDelivery[];
3540
+ }
3541
+ /**
3542
+ * Signed webhook payload delivered to subscriber endpoints.
3543
+ *
3544
+ * AtlaSent sets two headers on every delivery:
3545
+ * - `X-AtlaSent-Signature: sha256=<hex>` — HMAC-SHA256 of the raw body
3546
+ * - `X-AtlaSent-Event: <event_type>`
3547
+ *
3548
+ * Verify with `verifyWebhookSignature` before processing.
3549
+ */
3550
+ interface WebhookPayload<T = Record<string, unknown>> {
3551
+ id: string;
3552
+ org_id: string;
3553
+ event_type: string;
3554
+ source_id: string | null;
3555
+ data: T;
3556
+ created_at: string;
3557
+ }
3558
+ /**
3559
+ * Verify a webhook delivery signature using the subscription secret.
3560
+ *
3561
+ * Performs a constant-time HMAC-SHA256 comparison so timing attacks
3562
+ * cannot reveal secret length. Requires `globalThis.crypto.subtle`
3563
+ * (Node 20+, all modern browsers, Deno, Cloudflare Workers).
3564
+ *
3565
+ * @param payload Raw UTF-8 request body string.
3566
+ * @param signature Value of the `X-AtlaSent-Signature` header.
3567
+ * @param secret Webhook subscription secret from the AtlaSent console.
3568
+ * @returns `true` when the signature is valid.
3569
+ *
3570
+ * @example
3571
+ * ```ts
3572
+ * import { verifyWebhookSignature } from "@atlasent/sdk";
3573
+ *
3574
+ * app.post("/webhook", async (req, res) => {
3575
+ * const ok = await verifyWebhookSignature(
3576
+ * req.rawBody,
3577
+ * req.headers["x-atlasent-signature"],
3578
+ * process.env.WEBHOOK_SECRET!,
3579
+ * );
3580
+ * if (!ok) return res.status(401).send("invalid signature");
3581
+ * // process req.body …
3582
+ * });
3583
+ * ```
3584
+ */
3585
+ declare function verifyWebhookSignature(payload: string, signature: string, secret: string): Promise<boolean>;
3586
+
3587
+ /**
3588
+ * Compliance evidence types — wire shapes for `v1-compliance-evidence`.
3589
+ *
3590
+ * Supports on-demand SOC 2 Type II control evidence collection. The
3591
+ * same run shape is used for ISO 27001, GDPR, and HIPAA; control IDs
3592
+ * differ per framework.
3593
+ */
3594
+ type ComplianceFramework = "soc2" | "iso27001" | "gdpr" | "hipaa";
3595
+ type EvidenceControlStatus = "pass" | "gap" | "finding";
3596
+ type ComplianceRunStatus = "pending" | "running" | "completed" | "failed";
3597
+ /**
3598
+ * A single evaluated control within an evidence run.
3599
+ * `evidence` is a free-form object whose keys are framework-specific
3600
+ * metric names (e.g. `mfa_enforced_policies`, `audit_events_last_30d`).
3601
+ */
3602
+ interface EvidenceControl {
3603
+ control_id: string;
3604
+ title: string;
3605
+ status: EvidenceControlStatus;
3606
+ evidence: Record<string, unknown>;
3607
+ }
3608
+ interface ComplianceEvidenceSummary {
3609
+ total: number;
3610
+ pass: number;
3611
+ gap: number;
3612
+ finding: number;
3613
+ }
3614
+ interface ComplianceEvidenceRun {
3615
+ id: string;
3616
+ org_id: string;
3617
+ framework: ComplianceFramework;
3618
+ period_start: string;
3619
+ period_end: string;
3620
+ status: ComplianceRunStatus;
3621
+ controls: EvidenceControl[];
3622
+ summary: ComplianceEvidenceSummary | null;
3623
+ applied_by: string | null;
3624
+ created_at: string;
3625
+ }
3626
+ interface TriggerEvidenceRunRequest {
3627
+ framework: ComplianceFramework;
3628
+ /** ISO 8601 date string; defaults to 30 days ago on the server. */
3629
+ period_start?: string;
3630
+ /** ISO 8601 date string; defaults to now on the server. */
3631
+ period_end?: string;
3632
+ }
3633
+ interface TriggerEvidenceRunResponse {
3634
+ run: ComplianceEvidenceRun;
3635
+ }
3636
+ interface ListEvidenceRunsResponse {
3637
+ runs: ComplianceEvidenceRun[];
138
3638
  }
139
-
140
3639
  /**
141
- * Public types for the AtlaSent TypeScript SDK.
3640
+ * SOC 2 control IDs evaluated by `v1-compliance-evidence`.
142
3641
  *
143
- * These shapes are deliberately minimal and 1:1 with the AtlaSent
144
- * authorization API. Request / response fields are camelCase on the
145
- * SDK side; the client handles snake_case translation on the wire.
3642
+ * | ID | Area |
3643
+ * |--------|------|
3644
+ * | CC6.1 | MFA enforcement |
3645
+ * | CC6.3 | Periodic access reviews |
3646
+ * | CC7.2 | Audit trail completeness |
3647
+ * | CC8.1 | Change management / HITL |
3648
+ * | CC3.2 | Policy violations |
3649
+ */
3650
+ type SOC2ControlId = "CC6.1" | "CC6.3" | "CC7.2" | "CC8.1" | "CC3.2";
3651
+ /**
3652
+ * Returns `true` when every control in the run has `pass` or `gap`
3653
+ * status (no `finding`). A `gap` means a control is partially met;
3654
+ * a `finding` is a blocking deficiency that requires remediation.
3655
+ */
3656
+ declare function evidenceRunPasses(run: ComplianceEvidenceRun): boolean;
3657
+ /**
3658
+ * Returns controls that do not have `pass` status, sorted so
3659
+ * `finding` controls appear before `gap` controls.
146
3660
  */
3661
+ declare function nonPassingControls(run: ComplianceEvidenceRun): EvidenceControl[];
147
3662
 
148
- /** The two possible policy decisions. */
149
- type Decision = "ALLOW" | "DENY";
150
3663
  /**
151
- * Rate-limit state parsed from the server's `X-RateLimit-*` headers.
3664
+ * Policy-as-code GitOps sync types wire shapes for `v1-policy-sync`.
3665
+ *
3666
+ * Supports a dry-run diff preview / apply workflow for pushing policy
3667
+ * bundles from CI/CD pipelines or the AtlaSent console.
152
3668
  *
153
- * Present on every authenticated response (success and 429) when the
154
- * server emits the headers. `null` when the server doesn't — older
155
- * deployments, or internal endpoints that skip per-key rate limiting.
3669
+ * Typical flow:
3670
+ * 1. POST `{ policies, dry_run: true }` receive `run` with `diff`
3671
+ * 2. Review diff, then POST `/{run.id}/apply` to execute
156
3672
  *
157
- * Clients should check `remaining` and sleep until `resetAt` to
158
- * preemptively back off before hitting a 429.
3673
+ * Or POST `{ policies, dry_run: false }` for an immediate apply.
159
3674
  */
160
- interface RateLimitState {
161
- /** Value of `X-RateLimit-Limit` — the per-minute budget. */
162
- limit: number;
163
- /** Value of `X-RateLimit-Remaining` unused budget in the current window. */
164
- remaining: number;
165
- /**
166
- * Parsed `X-RateLimit-Reset` — the UTC instant when the current
167
- * window's counter zeroes. Accepts either a unix-seconds integer or
168
- * an ISO 8601 string on the wire.
169
- */
170
- resetAt: Date;
3675
+ type PolicySyncStatus = "pending" | "validating" | "applying" | "completed" | "failed" | "rejected";
3676
+ interface PolicyRef {
3677
+ name: string;
3678
+ /** SHA-256 hex of the policy body. */
3679
+ body_hash?: string;
171
3680
  }
172
- /** Input to {@link AtlaSentClient.evaluate}. */
173
- interface EvaluateRequest {
174
- /** Identifier of the calling agent (e.g. "clinical-data-agent"). */
175
- agent: string;
176
- /** The action being authorized (e.g. "modify_patient_record"). */
177
- action: string;
178
- /** Arbitrary policy context (user, environment, resource IDs). */
179
- context?: Record<string, unknown>;
3681
+ interface PolicySyncDiff {
3682
+ added: PolicyRef[];
3683
+ updated: PolicyRef[];
3684
+ removed: PolicyRef[];
180
3685
  }
181
- /** Result of {@link AtlaSentClient.evaluate}. */
182
- interface EvaluateResponse {
183
- /** "ALLOW" or "DENY". A "DENY" is not thrown — branch on this field. */
184
- decision: Decision;
185
- /** Opaque permit identifier, passed to {@link AtlaSentClient.verifyPermit}. */
186
- permitId: string;
187
- /** Human-readable explanation from the policy engine. */
188
- reason: string;
189
- /** Hash-chained audit-trail entry (21 CFR Part 11 / GxP-ready). */
190
- auditHash: string;
191
- /** ISO 8601 timestamp of the decision. */
192
- timestamp: string;
193
- /**
194
- * Per-key rate-limit state for this request's response, parsed from
195
- * `X-RateLimit-*` headers. `null` when the server didn't emit them.
196
- */
197
- rateLimit: RateLimitState | null;
3686
+ interface PolicySyncRun {
3687
+ id: string;
3688
+ org_id: string;
3689
+ /** Identifies the caller: `"console"`, `"github-actions"`, etc. */
3690
+ source: string;
3691
+ commit_sha: string | null;
3692
+ ref: string | null;
3693
+ bundle_hash: string | null;
3694
+ status: PolicySyncStatus;
3695
+ policies_added: number;
3696
+ policies_updated: number;
3697
+ policies_removed: number;
3698
+ /** Populated on dry-run; null after apply. */
3699
+ diff: PolicySyncDiff | null;
3700
+ applied_by: string | null;
3701
+ created_at: string;
198
3702
  }
199
- /** Input to {@link AtlaSentClient.verifyPermit}. */
200
- interface VerifyPermitRequest {
201
- /** The permit ID returned by a prior evaluate() call. */
202
- permitId: string;
203
- /** Optional: re-state the action for cross-check with the server. */
204
- action?: string;
205
- /** Optional: re-state the agent for cross-check with the server. */
206
- agent?: string;
207
- /** Optional: re-state the context for cross-check with the server. */
208
- context?: Record<string, unknown>;
3703
+ interface PolicyBundleEntry {
3704
+ name: string;
3705
+ /** Policy body OPA Rego, JSON schema, or custom DSL depending on config. */
3706
+ body: string;
3707
+ description?: string;
3708
+ tags?: string[];
209
3709
  }
210
- /** Result of {@link AtlaSentClient.verifyPermit}. */
211
- interface VerifyPermitResponse {
212
- /** `true` when the permit is valid and un-revoked. */
213
- verified: boolean;
214
- /** Verification outcome string from the server. */
215
- outcome: string;
216
- /** Verification hash bound to the permit. */
217
- permitHash: string;
218
- /** ISO 8601 timestamp of the verification. */
219
- timestamp: string;
3710
+ interface SubmitPolicySyncRequest {
3711
+ policies: PolicyBundleEntry[];
3712
+ /** Identifies the caller (e.g. `"github-actions"`, `"console"`). */
3713
+ source?: string;
3714
+ commit_sha?: string;
3715
+ ref?: string;
220
3716
  /**
221
- * Per-key rate-limit state for this request's response, parsed from
222
- * `X-RateLimit-*` headers. `null` when the server didn't emit them.
3717
+ * When `true` (default), computes the diff without applying changes.
3718
+ * The returned run will have `status: "pending"` and a populated `diff`.
3719
+ * POST to `/{run.id}/apply` to execute.
223
3720
  */
224
- rateLimit: RateLimitState | null;
3721
+ dry_run?: boolean;
225
3722
  }
226
- /**
227
- * Result of {@link AtlaSentClient.keySelf} — self-introspection of the API
228
- * key the client was constructed with. Returned by `GET /v1/api-key-self`.
229
- *
230
- * Never includes the raw key or its hash — introspection is intentionally
231
- * read-only and safe to surface in operator dashboards. Useful for:
232
- * - "which key am I?" debugging
233
- * - IP_NOT_ALLOWED failures — `clientIp` is the IP the server observed
234
- * - proactive expiry warnings — `expiresAt` is the server-stored expiry
235
- * (`null` means the key does not auto-expire)
236
- * - verifying scopes before attempting a scope-gated action
237
- */
238
- interface ApiKeySelfResponse {
239
- /** Server-side UUID of the api_keys row for this key. */
240
- keyId: string;
241
- /** Organization the key belongs to. */
242
- organizationId: string;
243
- /** "live" or "test" (or any future environment label the server introduces). */
244
- environment: string;
245
- /** Granted scopes — e.g. ["evaluate", "audit.read"]. */
246
- scopes: string[];
247
- /**
248
- * Per-key IP allowlist as CIDR strings (e.g. ["10.0.0.0/8"]). `null`
249
- * when the key is unrestricted.
250
- */
251
- allowedCidrs: string[] | null;
252
- /** Server-enforced per-minute rate limit for this key. */
253
- rateLimitPerMinute: number;
254
- /** Client IP as the server observed it (first hop of X-Forwarded-For). */
255
- clientIp: string | null;
256
- /** Server-stored expiry; `null` means the key does not auto-expire. */
257
- expiresAt: string | null;
258
- /**
259
- * Per-key rate-limit state for this request's response, parsed from
260
- * `X-RateLimit-*` headers. `null` when the server didn't emit them.
261
- */
262
- rateLimit: RateLimitState | null;
3723
+ interface SubmitPolicySyncResponse {
3724
+ run: PolicySyncRun;
263
3725
  }
264
- /**
265
- * Result of {@link AtlaSentClient.listAuditEvents}. Extends the raw
266
- * wire page with a camelCase `rateLimit` alongside the snake_case
267
- * wire fields — the wire shape (`events`, `total`, `next_cursor`) is
268
- * untouched so callers that pass it to the offline verifier get
269
- * byte-identical behaviour.
270
- */
271
- interface AuditEventsResult extends AuditEventsPage {
272
- /**
273
- * Per-key rate-limit state for this request's response, parsed from
274
- * `X-RateLimit-*` headers. `null` when the server didn't emit them.
275
- */
276
- rateLimit: RateLimitState | null;
3726
+ interface ListPolicySyncRunsResponse {
3727
+ runs: PolicySyncRun[];
3728
+ }
3729
+ interface ApplyPolicySyncResponse {
3730
+ run: PolicySyncRun;
277
3731
  }
278
3732
  /**
279
- * Filter accepted by {@link AtlaSentClient.createAuditExport}. Fields
280
- * are snake_case to match the server's `POST /v1-audit/exports`
281
- * request body; an empty object requests a full-org bundle.
3733
+ * Returns a human-readable one-line diff summary suitable for CI logs.
3734
+ *
3735
+ * @example
3736
+ * formatPolicySyncDiff(run) // "+3 added, ~1 updated, -2 removed"
3737
+ * formatPolicySyncDiff(run) // "no changes"
282
3738
  */
283
- interface AuditExportRequest {
284
- /** Comma-joined list of event types to include (e.g. `"evaluate.allow,policy.updated"`). */
285
- types?: string;
286
- /** Filter to a single actor. */
287
- actor_id?: string;
288
- /** Inclusive lower bound on `occurred_at` (ISO 8601). */
289
- from?: string;
290
- /** Inclusive upper bound on `occurred_at` (ISO 8601). */
291
- to?: string;
292
- }
3739
+ declare function formatPolicySyncDiff(run: Pick<PolicySyncRun, "policies_added" | "policies_updated" | "policies_removed">): string;
293
3740
  /**
294
- * Result of {@link AtlaSentClient.createAuditExport}. Extends the
295
- * signed bundle shape with a camelCase `rateLimit`. The signed
296
- * envelope fields (`export_id`, `org_id`, `chain_head_hash`,
297
- * `event_count`, `signed_at`, `events`, `signature`) are preserved
298
- * byte-for-byte so the object can be handed straight to
299
- * `verifyAuditBundle(bundle, keys)`.
3741
+ * Returns `true` when a sync run is in a terminal state
3742
+ * (completed, failed, or rejected) and no further transitions are expected.
300
3743
  */
301
- interface AuditExportResult extends AuditExport {
302
- /**
303
- * Per-key rate-limit state for this request's response, parsed from
304
- * `X-RateLimit-*` headers. `null` when the server didn't emit them.
305
- */
306
- rateLimit: RateLimitState | null;
307
- }
308
- /** Constructor options for {@link AtlaSentClient}. */
309
- interface AtlaSentClientOptions {
310
- /** Required. Your AtlaSent API key. */
311
- apiKey: string;
312
- /** API base URL. Defaults to "https://api.atlasent.io". */
313
- baseUrl?: string;
314
- /** Per-request timeout in milliseconds. Defaults to 10_000. */
315
- timeoutMs?: number;
316
- /**
317
- * Inject a fetch implementation (primarily for testing).
318
- * Defaults to `globalThis.fetch`.
319
- */
320
- fetch?: typeof fetch;
321
- }
3744
+ declare function isPolicySyncTerminal(run: PolicySyncRun): boolean;
322
3745
 
323
3746
  /**
324
- * AtlaSent HTTP client.
3747
+ * Webhook signature verification for AtlaSent.
325
3748
  *
326
- * Two public methods, both backed by native `fetch`:
327
- * - {@link AtlaSentClient.evaluate} → POST {baseUrl}/v1-evaluate
328
- * - {@link AtlaSentClient.verifyPermit} → POST {baseUrl}/v1-verify-permit
3749
+ * AtlaSent signs webhook payloads with HMAC-SHA256 using your webhook secret.
3750
+ * The signature is sent in the `X-AtlaSent-Signature` header as `sha256=<hex>`.
329
3751
  *
330
- * Fail-closed: a clean policy DENY is returned (not thrown), but
331
- * network, timeout, bad response, 4xx/5xx, and rate-limit conditions
332
- * all throw {@link AtlaSentError}.
3752
+ * Usage:
3753
+ * ```ts
3754
+ * import { verifyWebhook, assertWebhook, WebhookVerificationError } from "@atlasent/sdk";
3755
+ *
3756
+ * // Returns true/false — good for middleware that needs to continue on failure
3757
+ * const valid = verifyWebhook(rawBody, req.headers["x-atlasent-signature"], secret);
3758
+ *
3759
+ * // Throws WebhookVerificationError on failure — good for middleware that throws
3760
+ * assertWebhook(rawBody, req.headers["x-atlasent-signature"], secret);
3761
+ * ```
333
3762
  */
334
-
335
- declare class AtlaSentClient {
336
- private readonly apiKey;
337
- private readonly baseUrl;
338
- private readonly timeoutMs;
339
- private readonly fetchImpl;
340
- constructor(options: AtlaSentClientOptions);
341
- /**
342
- * Ask the policy engine whether an agent action is permitted.
343
- *
344
- * A "DENY" is **not** thrown — it is returned in
345
- * `response.decision`. Network errors, invalid API key, rate
346
- * limits, timeouts, and malformed responses throw
347
- * {@link AtlaSentError}.
348
- */
349
- evaluate(input: EvaluateRequest): Promise<EvaluateResponse>;
350
- /**
351
- * Verify that a previously issued permit is still valid.
352
- *
353
- * A `verified: false` response is **not** thrown — inspect the
354
- * returned object. Only transport / server errors throw.
355
- */
356
- verifyPermit(input: VerifyPermitRequest): Promise<VerifyPermitResponse>;
357
- /**
358
- * Self-introspection: ask the server to describe the API key this
359
- * client was constructed with. Returns the key's ID, organization,
360
- * environment, scopes, IP allowlist, per-minute rate limit, the
361
- * client IP the server observed, and the expiry (if any).
362
- *
363
- * Never includes the raw key or its hash. Safe to surface in operator
364
- * dashboards. Useful for `IP_NOT_ALLOWED` debugging (the server tells
365
- * you exactly which IP it saw) and for proactive expiry warnings.
366
- *
367
- * Throws {@link AtlaSentError} on transport / auth failures — same
368
- * taxonomy as {@link AtlaSentClient.evaluate}.
369
- */
370
- keySelf(): Promise<ApiKeySelfResponse>;
371
- /**
372
- * List persisted audit events for the authenticated organization
373
- * (`GET /v1-audit/events`). Returned rows are wire-identical with
374
- * the server: snake_case field names, including `previous_hash` and
375
- * the `hash` chain, so the response can be fed straight into the
376
- * offline verifier when paired with a signed export.
377
- *
378
- * `query.types` is a comma-joined list (e.g.
379
- * `"evaluate.allow,policy.updated"`). `cursor` is the opaque
380
- * `next_cursor` from the prior page. All fields are optional; the
381
- * server defaults `limit` to 50 (capped at 500).
382
- *
383
- * Throws {@link AtlaSentError} on transport / auth failures — same
384
- * taxonomy as {@link AtlaSentClient.evaluate}.
385
- */
386
- listAuditEvents(query?: AuditEventsQuery): Promise<AuditEventsResult>;
387
- /**
388
- * Request a signed audit export bundle
389
- * (`POST /v1-audit/exports`). The returned object is wire-identical
390
- * with the server — `signature`, `chain_head_hash`, `events`, and
391
- * friends survive untouched so the bundle can be persisted to disk
392
- * and handed to the offline verifier (`verifyBundle` /
393
- * `verifyAuditBundle`) without any reshaping.
394
- *
395
- * Pass `filter.types`, `filter.from`, `filter.to`, or `filter.actor_id`
396
- * to narrow the export; omit for a full-org bundle. `rateLimit` is
397
- * attached alongside the wire fields for observability.
398
- *
399
- * Throws {@link AtlaSentError} on transport / auth failures — same
400
- * taxonomy as {@link AtlaSentClient.evaluate}.
401
- */
402
- createAuditExport(filter?: AuditExportRequest): Promise<AuditExportResult>;
403
- private post;
404
- private get;
405
- private request;
406
- }
407
-
408
- /** Node's webcrypto CryptoKey — kept local so the module doesn't depend on DOM types. */
409
- type WebCryptoKey = webcrypto.CryptoKey;
410
- /** Public key candidate the verifier will try, tagged with its registry id. */
411
- interface VerifyKey {
412
- keyId: string;
413
- publicKey: WebCryptoKey;
414
- }
415
- interface BundleVerificationResult {
416
- /**
417
- * AND of three checks: adjacency (each event's `previous_hash`
418
- * equals the prior event's `hash`), per-event hash recomputation
419
- * from the canonical payload, and `chain_head_hash` matching the
420
- * last event's stored hash.
421
- */
422
- chainIntegrityOk: boolean;
423
- /** Ed25519 signature verified against one of the supplied public keys. */
424
- signatureValid: boolean;
425
- /** `chain_head_hash` equals the last event's stored `hash`. */
426
- headHashMatches: boolean;
427
- /** Event ids whose recomputed hash != stored hash. */
428
- tamperedEventIds: string[];
429
- /** Which registry key id matched, when `signatureValid` is true. */
430
- matchedKeyId?: string | undefined;
431
- /** Non-fatal explanation when a flag is false. */
432
- reason?: string | undefined;
433
- /** Convenience: `chainIntegrityOk && signatureValid`. */
434
- verified: boolean;
435
- }
436
- /** Parsed bundle shape the verifier consumes. Fields beyond these are ignored. */
437
- interface AuditBundle {
438
- export_id?: unknown;
439
- org_id?: unknown;
440
- chain_head_hash?: unknown;
441
- event_count?: unknown;
442
- signed_at?: unknown;
443
- events?: unknown;
444
- signature?: unknown;
445
- signing_key_id?: unknown;
446
- [k: string]: unknown;
447
- }
448
- interface VerifyBundleOptions {
449
- /** SPKI-PEM strings (one per key in the active trust set). */
450
- publicKeysPem?: readonly string[];
451
- /** Already-imported keys, paired with registry ids (rotation hint). */
452
- keys?: readonly VerifyKey[];
453
- }
454
3763
  /**
455
- * Reproduces `_shared/rules.ts::canonicalJSON` byte-for-byte:
456
- * - object keys sorted at every depth
457
- * - no whitespace
458
- * - `null`, `undefined`, `NaN`, `±Infinity` all render as `"null"`
459
- * - strings use standard `JSON.stringify` escapes
3764
+ * Thrown by {@link assertWebhook} when the signature is missing,
3765
+ * malformed, or does not match the payload.
460
3766
  */
461
- declare function canonicalJSON(value: unknown): string;
3767
+ declare class WebhookVerificationError extends Error {
3768
+ name: string;
3769
+ constructor(message: string);
3770
+ }
462
3771
  /**
463
- * Recreate the exact bytes `handleExport` signed. Key order is
464
- * load-bearing — must match the object literal in
465
- * `v1-audit/index.ts::handleExport`. V8 preserves insertion order, so
466
- * the literal below is byte-identical with what the backend signs.
3772
+ * Verifies an AtlaSent webhook payload signature.
3773
+ *
3774
+ * AtlaSent signs webhook payloads with HMAC-SHA256 using your webhook secret.
3775
+ * The signature is sent in the `X-AtlaSent-Signature` header as `"sha256=<hex>"`.
3776
+ *
3777
+ * @param payload - Raw request body as a string (do **not** parse before verifying)
3778
+ * @param signature - Value of the `X-AtlaSent-Signature` header
3779
+ * @param secret - Your webhook signing secret
3780
+ * @returns `true` if the signature is valid, `false` otherwise
3781
+ *
3782
+ * @remarks
3783
+ * Returns `false` (does not throw) for malformed or missing signatures.
3784
+ * Use {@link assertWebhook} if you prefer exception-based control flow.
467
3785
  */
468
- declare function signedBytesFor(bundle: AuditBundle): Uint8Array<ArrayBuffer>;
469
- declare function verifyAuditBundle(bundle: AuditBundle, keys: readonly VerifyKey[]): Promise<BundleVerificationResult>;
3786
+ declare function verifyWebhook(payload: string, signature: string, secret: string): Promise<boolean>;
470
3787
  /**
471
- * Load a bundle from disk (or a parsed object) and verify it.
3788
+ * Same as {@link verifyWebhook} but throws {@link WebhookVerificationError}
3789
+ * on failure instead of returning `false`. Useful in middleware where
3790
+ * throwing is cleaner than inspecting a boolean return value.
472
3791
  *
473
- * `publicKeysPem` is the active SPKI-PEM set from
474
- * `GET /v1-signing-keys`. When omitted, the chain check still runs
475
- * but `signatureValid` will be false with an explanatory `reason` —
476
- * callers that want a complete offline check MUST supply the trust
477
- * set.
3792
+ * @param payload - Raw request body as a string (do **not** parse before verifying)
3793
+ * @param signature - Value of the `X-AtlaSent-Signature` header
3794
+ * @param secret - Your webhook signing secret
3795
+ * @throws {@link WebhookVerificationError} if the signature is invalid or malformed
478
3796
  */
479
- declare function verifyBundle(pathOrBundle: string | AuditBundle, options?: VerifyBundleOptions): Promise<BundleVerificationResult>;
3797
+ declare function assertWebhook(payload: string, signature: string, secret: string): Promise<void>;
480
3798
 
481
3799
  /**
482
- * Retry-policy helpers for the AtlaSent TypeScript SDK.
3800
+ * V2 Wave-A endpoints (V2-D3, V2-D4, V2-D8) additive on top of v1.
483
3801
  *
484
- * This module is **pure**: no I/O, no network, no globals beyond
485
- * `Math.random`. The intent is that {@link AtlaSentClient} (and any
486
- * caller wrapping `protect()` / `evaluate()`) can ask
487
- * {@link isRetryable} whether to retry a given {@link AtlaSentError},
488
- * then ask {@link computeBackoffMs} how long to sleep before the next
489
- * attempt.
3802
+ * Three additional methods on top of the v1 {@link AtlaSentClient}
3803
+ * surface that target the new wire endpoints landed in `atlasent-api`
3804
+ * PRs #742 (batch), #745 (stream), and #746 (graphql).
490
3805
  *
491
- * Wire-up into the client itself is intentionally deferred see
492
- * ROADMAP item #7 (Post-GA). Sentry breadcrumb emission is also
493
- * deferred; both will land together once a transport-level retry
494
- * loop is wired into `client.ts`.
3806
+ * The v1 substrate is frozen (post-GA 2026-05-17)this module is
3807
+ * purely additive. Existing 1.x methods (`protect`, `requirePermit`,
3808
+ * `evaluate`, …) are untouched.
495
3809
  *
496
- * Retry classification (matches the server's documented contract):
497
- * - `network` / `timeout` → retry (transient transport)
498
- * - `server_error` (HTTP 5xx) → retry
499
- * - `rate_limited` (HTTP 429) → retry, honour `retryAfterMs`
500
- * - `bad_response` → retry (likely truncated body)
501
- * - `invalid_api_key`/`forbidden`/`bad_request` never retry
3810
+ * ## Closed-by-default discipline
3811
+ *
3812
+ * Each tenant gates the new endpoints behind `v2_batch`,
3813
+ * `v2_streaming`, and `v2_graphql` flags. When the flag is off the
3814
+ * API returns HTTP 404, surfaced here as {@link FeatureNotEnabledError}
3815
+ * so callers can deterministically fall back (typically to a per-item
3816
+ * `/v1-evaluate` loop). The SDK never silently falls back — that would
3817
+ * change billing and audit semantics.
3818
+ */
3819
+
3820
+ declare const V2_BATCH_PATH = "/v1/evaluate/batch";
3821
+ declare const V2_STREAM_PATH = "/v1/evaluate/stream";
3822
+ declare const V2_GRAPHQL_PATH = "/v1/graphql";
3823
+ /** Maximum items per batch (mirrors the server-side cap, V2-D3). */
3824
+ declare const V2_MAX_BATCH_ITEMS = 100;
3825
+ /** Maximum request body size (mirrors the server-side 1MB cap). */
3826
+ declare const V2_MAX_BODY_BYTES = 1000000;
3827
+ /** GraphQL document depth cap (V2-D2). */
3828
+ declare const V2_GRAPHQL_MAX_DEPTH = 8;
3829
+ /**
3830
+ * Identifier of the tenant flag gating a V2 endpoint.
3831
+ */
3832
+ type V2Feature = "batch" | "streaming" | "graphql";
3833
+ /**
3834
+ * Initialization options for {@link FeatureNotEnabledError}.
3835
+ */
3836
+ interface FeatureNotEnabledErrorInit {
3837
+ feature: V2Feature;
3838
+ endpoint: string;
3839
+ requestId?: string;
3840
+ }
3841
+ /**
3842
+ * Thrown when a V2 endpoint returns 404 because the tenant feature
3843
+ * flag is off.
502
3844
  *
503
- * Backoff: capped exponential with full jitter.
504
- * delay = min(maxDelayMs, baseDelayMs * 2^attempt) * random[0, 1)
3845
+ * The three V2 endpoints (`/v1/evaluate/batch`, `/v1/evaluate/stream`,
3846
+ * `/v1/graphql`) are close-by-default per tenant. When the
3847
+ * corresponding flag is unset, the API returns HTTP 404; the SDK
3848
+ * surfaces that as this distinct error so the caller can
3849
+ * deterministically fall back to the v1 per-item loop.
505
3850
  *
506
- * "Full jitter" is the AWS-recommended scheme — see
507
- * https://aws.amazon.com/blogs/architecture/exponential-backoff-and-jitter/.
508
- * It avoids thundering-herd retries from many SDK instances that hit
509
- * a 429 in the same window.
3851
+ * Subclass of {@link AtlaSentError} so `instanceof AtlaSentError`
3852
+ * catches it alongside the SDK's other typed errors.
510
3853
  */
511
- /** Defaults for {@link RetryPolicy}. Conservative — three retries, ~7s ceiling. */
512
- declare const DEFAULT_RETRY_POLICY: Required<RetryPolicy>;
3854
+ declare class FeatureNotEnabledError extends AtlaSentError {
3855
+ name: string;
3856
+ /** Which tenant flag is gating the endpoint. */
3857
+ readonly feature: V2Feature;
3858
+ /** The wire path the SDK attempted (for diagnostics). */
3859
+ readonly endpoint: string;
3860
+ constructor(init: FeatureNotEnabledErrorInit);
3861
+ }
513
3862
  /**
514
- * Caller-tunable retry policy. All fields optional; missing fields
515
- * fall back to {@link DEFAULT_RETRY_POLICY}.
3863
+ * One element of an {@link EvaluateBatchResponse.items} list.
3864
+ *
3865
+ * Preserves input order — `items[i]` corresponds to `request.items[i]`.
3866
+ * On a per-item RPC failure the server returns `decision: undefined`
3867
+ * and populates `errorCode` / `errorMessage` instead.
516
3868
  */
517
- interface RetryPolicy {
518
- /**
519
- * Total attempts including the first try. `1` disables retries
520
- * entirely. Must be `>= 1`; values below are clamped to `1`.
521
- */
522
- maxAttempts?: number;
523
- /**
524
- * Initial backoff for `attempt = 0`. Doubles per attempt up to
525
- * `maxDelayMs`. Must be `>= 0`.
526
- */
527
- baseDelayMs?: number;
528
- /**
529
- * Hard ceiling on the per-attempt sleep, applied **before** jitter.
530
- * The actual sleep is uniformly distributed in `[0, ceiling]`.
531
- */
532
- maxDelayMs?: number;
3869
+ interface EvaluateBatchItem {
3870
+ index: number;
3871
+ decision?: string;
3872
+ decisionId?: string;
3873
+ permitToken?: string;
3874
+ reason?: string;
3875
+ errorCode?: string;
3876
+ errorMessage?: string;
3877
+ }
3878
+ /** Response shape for `POST /v1/evaluate/batch`. */
3879
+ interface EvaluateBatchResponse {
3880
+ batchId: string;
3881
+ items: ReadonlyArray<EvaluateBatchItem>;
3882
+ partial: boolean;
3883
+ }
3884
+ /** Request payload for {@link evaluateMany} and {@link authorizeStream}. */
3885
+ interface EvaluateManyRequest {
3886
+ items: ReadonlyArray<Record<string, unknown>>;
3887
+ batchId?: string;
3888
+ }
3889
+ /** `event: decision` frame surfaced via the `onDecision` callback. */
3890
+ interface StreamDecisionFrame {
3891
+ index: number;
3892
+ decision: string;
3893
+ decisionId?: string;
3894
+ permitToken?: string;
3895
+ reason?: string;
3896
+ }
3897
+ /** `event: error` frame surfaced via the `onError` callback. */
3898
+ interface StreamErrorFrame {
3899
+ index: number;
3900
+ errorCode: string;
3901
+ message: string;
3902
+ }
3903
+ /** Terminal `event: complete` payload returned by {@link authorizeStream}. */
3904
+ interface StreamComplete {
3905
+ batchId: string;
3906
+ count: number;
3907
+ partial: boolean;
3908
+ }
3909
+ /** GraphQL request body. */
3910
+ interface GraphQLRequest {
3911
+ query: string;
3912
+ variables?: Record<string, unknown>;
3913
+ operationName?: string;
3914
+ }
3915
+ /**
3916
+ * GraphQL response. Resolver errors land on `errors`; the SDK does
3917
+ * not throw on them — the caller branches.
3918
+ */
3919
+ interface GraphQLResponse<T = unknown> {
3920
+ data: T | null;
3921
+ errors?: ReadonlyArray<Record<string, unknown>>;
533
3922
  }
534
3923
  /**
535
- * Decide whether `err` is worth a retry. Anything that isn't an
536
- * {@link AtlaSentError} is treated as non-retryable the SDK's
537
- * transport layer always wraps fetch failures in `AtlaSentError`,
538
- * so a non-AtlaSent throwable is by definition a programmer bug
539
- * (a bad input, an assertion in user code) and should propagate.
3924
+ * The minimal subset of an {@link AtlaSentClient}-like object this
3925
+ * module needs: a `fetch`-compatible HTTP function and a base URL.
3926
+ *
3927
+ * Passed explicitly so the v2 module never reaches into v1 internals
3928
+ * (and so callers can plug in a custom fetch for testing / edge
3929
+ * runtimes / Node fetch wrappers).
540
3930
  */
541
- declare function isRetryable(err: unknown): boolean;
3931
+ interface V2Transport {
3932
+ /** Base URL (no trailing slash), e.g. `https://api.atlasent.io`. */
3933
+ baseUrl: string;
3934
+ /** Bearer API key (without the `Bearer ` prefix). */
3935
+ apiKey: string;
3936
+ /** A `fetch`-like function. Defaults to global `fetch` if omitted. */
3937
+ fetch?: typeof fetch;
3938
+ }
542
3939
  /**
543
- * Compute how long to sleep before retry attempt `attempt`
544
- * (zero-indexed: `attempt = 0` is the first retry, i.e. the second
545
- * total request). Uses capped exponential backoff with full jitter.
3940
+ * `POST /v1/evaluate/batch` V2-D3.
546
3941
  *
547
- * When `err` carries a `retryAfterMs` (server-provided `Retry-After`
548
- * header), the result is `max(retryAfterMs, jitteredDelay)`the
549
- * server's hint is treated as a floor so we never retry sooner than
550
- * the server asked.
3942
+ * One round-trip for up to {@link V2_MAX_BATCH_ITEMS} evaluate items.
3943
+ * Items are returned in input order`response.items[i].index === i`.
551
3944
  *
552
- * @param attempt Zero-indexed retry attempt (0, 1, 2, ...).
553
- * @param policy Optional override of {@link DEFAULT_RETRY_POLICY}.
554
- * @param err Optional error whose `retryAfterMs` is honoured.
555
- * @param random Injectable RNG, defaults to `Math.random`. Must
556
- * return values in `[0, 1)` to preserve the
557
- * distribution.
3945
+ * @throws {FeatureNotEnabledError} When the tenant `v2_batch` flag is off (404).
3946
+ * @throws {AtlaSentError} For any other transport / HTTP failure.
3947
+ * @throws {TypeError} When `items` is empty, exceeds the cap, or
3948
+ * `batchId` is not a valid UUID.
558
3949
  */
559
- declare function computeBackoffMs(attempt: number, policy?: RetryPolicy, err?: unknown, random?: () => number): number;
3950
+ declare function evaluateMany(transport: V2Transport, req: EvaluateManyRequest): Promise<EvaluateBatchResponse>;
560
3951
  /**
561
- * Returns `true` when `attempt` (zero-indexed) is below the policy's
562
- * `maxAttempts - 1` ceiling — i.e. when there is still budget for at
563
- * least one more try after this one. Convenience wrapper so retry
564
- * loops read top-to-bottom:
3952
+ * Callbacks consumed by {@link authorizeStream}.
3953
+ */
3954
+ interface AuthorizeStreamHandlers {
3955
+ onDecision?: (frame: StreamDecisionFrame) => void;
3956
+ onError?: (frame: StreamErrorFrame) => void;
3957
+ }
3958
+ /**
3959
+ * `POST /v1/evaluate/stream` — V2-D4.
565
3960
  *
566
- * ```ts
567
- * for (let attempt = 0; ; attempt++) {
568
- * try { return await op(); }
569
- * catch (err) {
570
- * if (!isRetryable(err) || !hasAttemptsLeft(attempt, policy)) throw err;
571
- * await sleep(computeBackoffMs(attempt, policy, err));
572
- * }
573
- * }
574
- * ```
3961
+ * Streams `event: decision` frames in input order. Per-item RPC
3962
+ * failures arrive as `event: error` frames and do not tear down the
3963
+ * stream (V2-D7 async semantics). Resolves with the terminal
3964
+ * `event: complete` payload.
3965
+ *
3966
+ * @throws {FeatureNotEnabledError} When the tenant `v2_streaming` flag is off.
3967
+ * @throws {AtlaSentError} For transport failures, including the stream
3968
+ * closing without a `complete` frame.
575
3969
  */
576
- declare function hasAttemptsLeft(attempt: number, policy?: RetryPolicy): boolean;
3970
+ declare function authorizeStream(transport: V2Transport, req: EvaluateManyRequest, handlers?: AuthorizeStreamHandlers): Promise<StreamComplete>;
577
3971
  /**
578
- * Merge a partial policy with {@link DEFAULT_RETRY_POLICY} and clamp
579
- * each field into a sensible range. Exported for tests and for
580
- * callers that want to log the resolved policy.
3972
+ * `POST /v1/graphql` V2-D2 + V2-D8.
3973
+ *
3974
+ * Bearer-only auth (no query-param). Wave A schema is read-only
3975
+ * (`recentEvaluations(limit)` + `activeBundle`). Server enforces the
3976
+ * V2-D8 OR-gate (`audit:read` OR `policy:read`) at request layer and
3977
+ * a per-resolver AND-gate at field resolution time.
3978
+ *
3979
+ * Resolver-level errors surface on `response.errors` — the SDK does
3980
+ * not throw on them so callers can inspect partial data.
3981
+ *
3982
+ * @throws {FeatureNotEnabledError} When the tenant `v2_graphql` flag is off.
3983
+ * @throws {AtlaSentError} For transport / HTTP failures.
3984
+ * @throws {TypeError} When `query` is empty or the body exceeds the 1MB cap.
581
3985
  */
582
- declare function mergePolicy(policy: RetryPolicy): Required<RetryPolicy>;
3986
+ declare function graphql<T = unknown>(transport: V2Transport, req: GraphQLRequest): Promise<GraphQLResponse<T>>;
583
3987
 
584
3988
  /**
585
3989
  * @atlasent/sdk — execution-time authorization for AI agents.
586
3990
  *
587
- * Primary API is the default export:
3991
+ * The canonical execution-boundary surface is two forms of the same
3992
+ * contract. Both mint and verify a Permit end-to-end; both fail closed.
3993
+ * Pick the form that fits the call site.
3994
+ *
3995
+ * `protect` — the primitive. Returns the verified {@link Permit} so
3996
+ * the caller can pass it across a boundary, persist it alongside
3997
+ * their own record, or interleave it with non-trivial control flow:
588
3998
  *
589
3999
  * ```ts
590
4000
  * import atlasent from "@atlasent/sdk";
591
4001
  *
592
4002
  * const permit = await atlasent.protect({
593
4003
  * agent: "deploy-bot",
594
- * action: "deploy_to_production",
4004
+ * action: "production.deploy",
595
4005
  * context: { commit, approver },
596
4006
  * });
4007
+ * // permit is verified end-to-end. Execute the action.
4008
+ * ```
4009
+ *
4010
+ * `withPermit` — the lexically-scoped form. Binds the action body to
4011
+ * the permit's lifetime via a callback so the call site reads as
4012
+ * "execute this body under a permit":
4013
+ *
4014
+ * ```ts
4015
+ * const result = await atlasent.withPermit(
4016
+ * { agent: "deploy-bot", action: "production.deploy",
4017
+ * context: { commit, approver } },
4018
+ * async (permit) => runDeploy(commit, { permitId: permit.permitId }),
4019
+ * );
4020
+ * ```
4021
+ *
4022
+ * `requirePermit` — descriptor form for dangerous operations carrying
4023
+ * `resource_id` + `environment`. The executor only runs when AtlaSent
4024
+ * authorizes it end-to-end:
4025
+ *
4026
+ * ```ts
4027
+ * await atlasent.requirePermit(
4028
+ * { action_type: "database.table.drop", actor_id: "agent:code-agent",
4029
+ * resource_id: "prod-db.users", environment: "production",
4030
+ * context: { reversibility: "irreversible" } },
4031
+ * async () => { await db.raw("DROP TABLE users"); },
4032
+ * );
597
4033
  * ```
598
4034
  *
599
4035
  * Named exports remain available for the lower-level
@@ -605,16 +4041,24 @@ declare function mergePolicy(policy: RetryPolicy): Required<RetryPolicy>;
605
4041
  *
606
4042
  * ```ts
607
4043
  * import atlasent from "@atlasent/sdk";
608
- * await atlasent.protect({ ... });
4044
+ * const permit = await atlasent.protect({ ... }); // primitive
4045
+ * await atlasent.withPermit({ ... }, async (permit) => …); // scoped form
4046
+ * await atlasent.requirePermit({ ... }, executor); // descriptor form
609
4047
  * ```
610
4048
  */
611
4049
  declare const atlasent: {
612
4050
  readonly protect: typeof protect;
4051
+ readonly withPermit: typeof withPermit;
4052
+ readonly deployGate: typeof deployGate;
613
4053
  readonly configure: typeof configure;
4054
+ readonly requirePermit: typeof requirePermit;
4055
+ readonly classifyCommand: typeof classifyCommand;
614
4056
  readonly verifyBundle: typeof verifyBundle;
4057
+ readonly PRODUCTION_DEPLOY_ACTION: "production.deploy";
4058
+ readonly DEPLOYMENT_PRODUCTION_ACTION: "deployment.production";
615
4059
  readonly AtlaSentClient: typeof AtlaSentClient;
616
4060
  readonly AtlaSentError: typeof AtlaSentError;
617
4061
  readonly AtlaSentDeniedError: typeof AtlaSentDeniedError;
618
4062
  };
619
4063
 
620
- export { type ApiKeySelfResponse, AtlaSentClient, type AtlaSentClientOptions, AtlaSentDeniedError, AtlaSentError, type AuditBundle, type AuditDecision, type AuditEvent, type AuditEventsPage, type AuditEventsQuery, type AuditEventsResult, type AuditExport, type AuditExportRequest, type AuditExportResult, type AuditExportSignatureStatus, type BundleVerificationResult, DEFAULT_RETRY_POLICY, type Decision, type EvaluateRequest, type EvaluateResponse, type RateLimitState, type RetryPolicy, type VerifyBundleOptions, type VerifyKey, type VerifyPermitRequest, type VerifyPermitResponse, canonicalJSON, computeBackoffMs, configure, atlasent as default, hasAttemptsLeft, isRetryable, mergePolicy, protect, signedBytesFor, verifyAuditBundle, verifyBundle };
4064
+ export { type ActionFreeze, type ActionTypeOverrideStat, type ActorOverrideStat, type AmountThreshold, type AnomalyActionType, type AnomalyResponseEvent, type AnomalyResponseRule, type AnomalyType, ApiKeySelfResponse, type ApplyPolicySyncResponse, type ApprovalArtifactV1, type ApprovalConcentrationAnalysis, type ApprovalIssuer, type ApprovalProvenance, type ApprovalQuorumV1, type ApprovalReference, type ApprovalReviewer, type ApproveBudgetExceptionRequest, type ApproverBreakdown, AtlaSentClient, AtlaSentClientOptions, AtlaSentDeniedError, AtlaSentError, type AuditBundle, AuditEventsQuery, AuditEventsResult, AuditExportRequest, AuditExportResult, type AuthenticateConnectorInput, type AuthenticateConnectorResponse, type AuthorizeStreamHandlers, type AutonomousBoundsDenyCode, type AutonomousExecutionBounds, type AutonomousExecutionCheckResult, type AutonomousExecutionRecord, type BudgetConstraintCheckResult, type BudgetDenyCode, type BudgetExceptionRequest, type BudgetExceptionStatus, type BudgetLimit, type BudgetPolicy, type BudgetScope, type BudgetSpendingState, type BudgetViolation, type BudgetaryDriftAnalysis, type BundleVerificationResult, type ComplianceEvidenceRun, type ComplianceEvidenceSummary, type ComplianceFramework, type ComplianceRunStatus, type ComputeOrgRiskOptions, type ComputeOrgRiskResponse, type ConcentrationAlert, type ConnectedSystemRow, type ConnectorAuditLogEntry, type ConnectorCredentialRow, type ConnectorCredentialType, type ConnectorEnforcementEventInput, type ConnectorEnforcementPolicy, type ConnectorEnforcementResult, type ConnectorRow, type ConnectorStatus, type ConnectorSyncState, type ConnectorType, type CreateAnomalyResponseRuleRequest, type CreateBudgetExceptionRequest, type CreateGraphEdgeInput, type CreateGraphNodeInput, type CreateImpersonationGrantRequest, type CreateOverrideRequest, type CreateRegulatoryEscalationRequest, type CreateWebhookSubscriptionRequest, type CrossOrgImpersonationGrant, type CrossOrgPermissionCheckListParams, type CrossOrgPermissionCheckRequest, type CrossOrgPermissionCheckResult, type CrossOrgTrustHop, type CurrencyCode, DEFAULT_INCENTIVE_CONFIG, DEFAULT_RISK_TIER_THRESHOLDS, type DelegationPropagationSummary, DeployGateRequest, DeployGateResponse, type DisputeOrigin, type DisputeRecord, type DisputeReversalSummary, type DisputeStatus, type EconomicEvidenceBundle, type EmergencyFreeze, type EmergencyOverrideActionRow, type EnforcementAction, type EnforcementQuorumConfig, type EnforcementWebhookEvent, type EvaluateBatchItem, type EvaluateBatchResponse, type EvaluateManyRequest, EvaluatePreflightResponse, EvaluateRequest, EvaluateResponse, type EvidenceBundleSignableContent, type EvidenceBundleVerificationResult, type EvidenceControl, type EvidenceControlStatus, type EvidencePurpose, type ExecutionAnomaly, type ExecutionApproverRow, type ExecutionCeiling, FeatureNotEnabledError, type FeatureNotEnabledErrorInit, type FinancialActionClass, type FinancialActionType, type FinancialExecutionRecord, type FinancialExecutionStatus, type FinancialGovernanceSummary, type FinancialQuorumDenyCode, type FinancialQuorumInput, type FinancialQuorumPolicy, type FinancialQuorumResult, type FinancialRiskScore, type FinancialRiskTier, type FinancialRoleRequirement, type GetLatestOrgRiskResponse, GetPermitResponse, type GovernanceBehaviorPattern, GovernanceEnforcementError, type GovernanceEnforcementErrorInit, type GovernanceEvent, type GovernanceGate, type GovernanceGraphQueryParams, type GovernanceGraphQueryResponse, type GovernanceGraphQueryType, type GovernanceGraphResultRow, type GovernanceSignalAction, type GovernanceWebhookEvent, type GraphEdge, type GraphEdgeType, type GraphNode, type GraphNodeType, type GraphQLRequest, type GraphQLResponse, type HitlAiUnavailableFallback, type HitlApprovalRecord, type HitlApproveRequest, type HitlApproverPoolEntry, type HitlApproverType, type HitlChainHop, type HitlCreateRequest, type HitlDetailResponse, type HitlEscalateRequest, type HitlEscalation, type HitlFallbackDecision, type HitlHeterogeneousQuorumExtension, type HitlHeterogeneousQuorumTally, type HitlListResponse, type HitlQuorumProgress, type HitlQuorumTier, type HitlRejectRequest, type HitlRespondRequest, type HitlStatus, type IdentityAssertionBinding, type IdentityAssertionV1, type IdentityIssuer, type IdentityIssuerKey, type IdentitySubject, type IdentityTrustedIssuersConfig, type ImpersonationToken, type ImpersonationValidationResult, type IncentiveAlignmentConfig, type IncentiveSignal, type IncentiveSignalType, type IncidentChainActorEntry, type IncidentChainEvidenceRow, type IncidentChainExecutionRow, type IncidentTimelineResponse, type InstallConnectorInput, type InstallConnectorResponse, type LegacyEvaluateRequest, type LegacyEvaluateResponse, type LiabilityAttributionInput, type LiabilityAttributionRecord, type LiabilityChainValidation, type LiabilityClassification, type LiabilityEdge, type LiabilityNode, type LiabilityParty, type LiabilityPartyRole, type LiabilityVisualization, type ListConnectorsResponse, type ListEnforcementPoliciesResponse, type ListEvidenceRunsResponse, type ListGraphEdgesResponse, type ListGraphNodesResponse, type ListHitlEscalationsRequest, type ListHitlEscalationsResponse, type ListOrgRiskHistoryResponse, ListPermitsRequest, ListPermitsResponse, type ListPolicySyncRunsResponse, type ListWebhookDeliveriesResponse, type ListWebhookSubscriptionsResponse, type MisalignmentAlert, type OrgRiskLevel, type OrgRiskScore, type OverrideAnalytics, type OverrideEvent, type OverrideEventType, type OverrideEventsResponse, type OverrideListResponse, type OverrideStatus, type OverrideV1, Permit, type PermitV1, PermitValidResponse, type PolicyBundleEntry, type PolicyRef, type PolicySyncDiff, type PolicySyncRun, type PolicySyncStatus, type PrincipalKind, type ProductionDeployerRow, type ProofEvaluationSummary, type ProofPayload, type ProofResponse, ProtectRequest, type ProtectedAction, type QuorumBypassConnectorRow, type QuorumIndependence, type QuorumPolicy, type QuorumProof, type QuorumRoleRequirement, RateLimitState, type RecordSignalActionRequest, type RecordSignalOutcomeRequest, type RegulatoryAuthorityLevel, type RegulatoryEscalation, type RegulatoryEscalationStatus, type ReversalStage, type ReversalWorkflow, type RevokeConnectorResponse, RevokePermitByIdInput, RevokePermitByIdResponse, RevokePermitRequest, RevokePermitResponse, type RiskFactor, type RiskTierThreshold, type RiskTimelinePoint, type RotateCredentialsResponse, type SOC2ControlId, type SandboxDiff, type SandboxDiffEmpty, type SandboxDiffPerTable, type SandboxDiffResponse, type SandboxRunMode, type SandboxRunStatus, type SandboxRunWrite, type SandboxWriteOp, type SignalActionSummary, type SignalActionType, type SpendingConstraint, type StreamComplete, type StreamDecisionFrame, type StreamErrorFrame, StreamEvent, StreamOptions, type SubmitPolicySyncRequest, type SubmitPolicySyncResponse, type SyncConnectorResponse, type TriggerAnomalyResponseRequest, type TriggerEvidenceRunRequest, type TriggerEvidenceRunResponse, type UpsertEnforcementPolicyInput, type UpsertEnforcementPolicyResponse, type UserApprovalRow, type V2EvaluateRequest, type V2EvaluateResponse, type V2Feature, type V2Transport, V2_BATCH_PATH, V2_GRAPHQL_MAX_DEPTH, V2_GRAPHQL_PATH, V2_MAX_BATCH_ITEMS, V2_MAX_BODY_BYTES, V2_STREAM_PATH, type VerifyBundleOptions, type VerifyKey, VerifyPermitByIdResponse, VerifyPermitRequest, VerifyPermitResponse, type WebhookDelivery, type WebhookDeliveryStatus, type WebhookPayload, type WebhookSubscription, WebhookVerificationError, type WeightDistribution, assertWebhook, authorizeStream, budgetUtilizationSeverity, buildLiabilityChain, buildLiabilityVisualization, buildRiskTimeline, buildSignableContent, canonicalJSON, canonicalizeForEvidence, checkAutonomousBounds, checkBudgetConstraints, clampTokenDuration, classifyCommand, classifyRiskTier, computeApprovalRiskScore, computeEscalatedApprovalCount, computeExposureScore, computeGovernanceHealthScore, computeHHI, computeLiabilityWeights, computeOverallRiskScore, computeOverrideScore, computeRemediationUrgency, computeSignalEngagementRate, configure, atlasent as default, delegationPropagationHadEffect, deployGate, detectAutonomousAnomaly, detectMisalignedIncentives, detectSelfApproval, enforceAutonomousBounds, enforceBudgetConstraint, enforceEconomicGovernance, enforceFinancialQuorum, evaluateFinancialQuorum, evaluateMany, evidenceRunPasses, findPrimaryLiabilityParties, formatPolicySyncDiff, graphql, hhiToConcentrationScore, highestSeverityAction, hitlRequiredApproverCount, isBudgetExceptionActive, isBudgetExceptionTerminal, isEscalationSlaBreached, isFreezeActive, isImpersonationGrantUsable, isPolicySyncTerminal, isRegulatoryEscalationTerminal, isSandboxDiffPopulated, isSubstantiveSignalResponse, matchAnomalyRules, nonPassingControls, normalizeEvaluateRequest, normalizeEvaluateResponse, protect, requirePermit, scoreToRiskTier, serializeSignableContent, signedBytesFor, summarizeCrossOrgPermission, transitionDispute, transitionReversal, validateLiabilityChain, verifyAuditBundle, verifyBundle, verifyEvidenceBundleStructure, verifyWebhook, verifyWebhookSignature, withPermit, withinAutonomousCeiling };