@splitin/verification-engine 0.1.0-beta.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.
@@ -0,0 +1,737 @@
1
+ import { VerificationProviderCode, VerificationProviderEnvironment, VerificationAdapterV1, VerificationPackageCode, VerificationCanonicalStatus, ActorContext, ProtectedActionDenial, ProviderOrganizationInput, ProviderRelationshipInput, ProviderLaunchEnvelope } from '@splitin/verification-adapter-sdk';
2
+ export { ActorContext, ProtectedActionDenial, VerificationCanonicalStatus, VerificationPackageCode, VerificationProviderCode, VerificationProviderEnvironment } from '@splitin/verification-adapter-sdk';
3
+
4
+ type EngineErrorCode = 'AUTHORIZATION_DENIED' | 'CLIENT_ROUTE_INJECTION' | 'NO_ELIGIBLE_ROUTE' | 'ATTEMPT_NOT_FOUND' | 'ATTEMPT_PINNED' | 'ATTEMPT_TERMINAL' | 'OPERATION_PENDING' | 'PRODUCTION_NOT_ACTIVATED' | 'WEBHOOK_SECURITY_INCIDENT' | 'WEBHOOK_UNAUTHENTICATED' | 'CONTINUATION_DENIED' | 'GOVERNANCE_TWO_ACTOR' | 'INVALID_TRANSITION' | 'INVALID_COMMAND' | 'PROVIDER_UNAVAILABLE' | 'DESTINATION_NOT_ALLOWLISTED';
5
+ declare class EngineError extends Error {
6
+ readonly code: EngineErrorCode;
7
+ readonly retryable: boolean;
8
+ readonly retryAfterSeconds?: number | undefined;
9
+ constructor(code: EngineErrorCode, message: string, retryable?: boolean, retryAfterSeconds?: number | undefined);
10
+ }
11
+ declare class AuthorizationError extends EngineError {
12
+ constructor(message?: string);
13
+ }
14
+ declare class ClientRouteInjectionError extends EngineError {
15
+ constructor(message?: string);
16
+ }
17
+ declare class WebhookSecurityIncidentError extends EngineError {
18
+ constructor(message?: string);
19
+ }
20
+
21
+ /** Canonical JSON: recursively sorted object keys, no insignificant whitespace. */
22
+ declare function canonicalize(value: unknown): string;
23
+ declare function digestCanonical(value: unknown): Promise<string>;
24
+
25
+ declare function sha256Hex(payload: string | Uint8Array): Promise<string>;
26
+ declare function hmacSha256Hex(secret: string, payload: string | Uint8Array): Promise<string>;
27
+ declare function cohortBucket(tenantKey: string, subjectHash: string): Promise<number>;
28
+
29
+ interface ProviderRegistry {
30
+ get(provider: VerificationProviderCode, environment?: VerificationProviderEnvironment): VerificationAdapterV1;
31
+ list(): VerificationAdapterV1[];
32
+ has(provider: VerificationProviderCode): boolean;
33
+ }
34
+ /**
35
+ * Explicit code imports only. Database rows cannot load packages.
36
+ */
37
+ declare function createProviderRegistry(input: {
38
+ adapters: VerificationAdapterV1[];
39
+ }): ProviderRegistry;
40
+
41
+ declare const FORBIDDEN_CLIENT_ROUTE_KEYS: readonly ["provider", "templateId", "template_id", "workflowId", "workflow_id", "apiOrigin", "api_origin", "configurationRevision", "configuration_revision", "adapterVersion", "manifestDigest", "policyVersion", "routeId"];
42
+ declare const LIVE_ATTEMPT_STATUSES: VerificationCanonicalStatus[];
43
+ declare const GOVERNANCE_TRANSITIONS: readonly ["approve", "deny", "request_more_information", "revoke", "expire"];
44
+ type GovernanceTransition = (typeof GOVERNANCE_TRANSITIONS)[number];
45
+ type CircuitState = 'closed' | 'open' | 'half_open';
46
+ type RouteLifecycle = 'draft' | 'approved' | 'active' | 'retired';
47
+ type PolicyLifecycle = 'draft' | 'approved' | 'active' | 'retired';
48
+ type IdempotencyState = 'claimed' | 'completed' | 'failed';
49
+ type WebhookEventState = 'accepted' | 'processing' | 'completed' | 'retryable' | 'dead_letter';
50
+ type RedactionStatus = 'scheduled' | 'processing' | 'retryable' | 'redacted' | 'not_applicable' | 'dead_letter';
51
+ type QueueJobKind = 'webhook' | 'reconcile' | 'redact';
52
+ type AppealStatus = 'open' | 'approved' | 'denied' | 'more_information_requested' | 'revoked' | 'expired';
53
+ type ReviewStatus = AppealStatus | 'in_review';
54
+ type ProposalStatus = 'proposed' | 'approved' | 'rejected';
55
+ type DecisionStatus = 'verified' | 'declined' | 'revoked' | 'expired';
56
+ /** Application-defined reason codes the SDK stores without interpreting housing or biometric policy. */
57
+ declare const APPLICATION_REASON_CODES: readonly ["underage", "unsupported_capability", "biometric_alternative_requested", "manual_review_required", "document_unreadable", "more_information_requested"];
58
+ declare function isApplicationReasonCode(value: string): value is ApplicationReasonCode;
59
+ type ApplicationReasonCode = (typeof APPLICATION_REASON_CODES)[number];
60
+ type EngineOperation = 'start' | 'resume' | 'status' | 'retry' | 'pause' | 'cancel' | 'redact' | 'ingest_webhook' | 'process_webhook' | 'reconcile' | 'appeal' | 'review' | 'evaluate_protected_action' | 'admin.health' | 'admin.routes' | 'admin.circuits' | 'admin.attempts' | 'admin.audit' | 'admin.propose_route' | 'admin.approve_route' | 'admin.propose_policy' | 'admin.approve_policy' | 'admin.activate_policy' | 'admin.emergency_drain';
61
+ interface AuthorizeFn {
62
+ (actor: ActorContext, operation: EngineOperation, resource: {
63
+ type: string;
64
+ id?: string;
65
+ }): Promise<boolean> | boolean;
66
+ }
67
+ interface EngineRuntime {
68
+ now?: () => Date;
69
+ crypto?: Crypto;
70
+ productionEnabled?: boolean;
71
+ seedSandboxExamples?: boolean;
72
+ continuationTtlSeconds?: number;
73
+ webhookLeaseSeconds?: number;
74
+ maxWorkerAttempts?: number;
75
+ workerConcurrency?: number;
76
+ defaultDecisionTtlSeconds?: number;
77
+ rateBudgetPerProvider?: number;
78
+ random?: () => number;
79
+ }
80
+ interface StartVerificationCommand {
81
+ packageCode: VerificationPackageCode;
82
+ countryCode: string;
83
+ subjectReference: string;
84
+ idempotencyKey: string;
85
+ action?: string | null;
86
+ resourceType?: string | null;
87
+ resourceReference?: string | null;
88
+ organization?: ProviderOrganizationInput | null;
89
+ relationship?: ProviderRelationshipInput | null;
90
+ associatedPerson?: ProviderAssociatedPersonLike | null;
91
+ legalFirstName?: string | null;
92
+ legalLastName?: string | null;
93
+ email?: string | null;
94
+ requestOrigin?: string | null;
95
+ metadata?: Record<string, string | number | boolean | null>;
96
+ evidenceReferences?: string[];
97
+ }
98
+ interface ProviderAssociatedPersonLike {
99
+ subjectReference: string;
100
+ legalFirstName: string;
101
+ legalLastName: string;
102
+ email?: string | null;
103
+ relationshipKind: string;
104
+ claimedOwnershipPercentage?: number | null;
105
+ }
106
+ interface ResumeVerificationCommand {
107
+ attemptId: string;
108
+ requestOrigin?: string | null;
109
+ }
110
+ interface RetryVerificationCommand extends StartVerificationCommand {
111
+ parentAttemptId: string;
112
+ }
113
+ interface RedactCommand {
114
+ subjectReference: string;
115
+ attemptId?: string | null;
116
+ requestReference?: string | null;
117
+ }
118
+ interface ProtectedActionCommand {
119
+ action: string;
120
+ resourceType: string;
121
+ resourceReference: string;
122
+ subjectReference: string;
123
+ destinationKey?: string;
124
+ }
125
+ interface IngestWebhookCommand {
126
+ provider: VerificationProviderCode;
127
+ request: Request;
128
+ tenantKey: string;
129
+ }
130
+ interface AppealSubmitCommand {
131
+ attemptId: string;
132
+ reason: string;
133
+ expiresAt?: string | null;
134
+ }
135
+ interface AppealTransitionCommand {
136
+ appealId: string;
137
+ transition: GovernanceTransition;
138
+ reason: string;
139
+ }
140
+ interface ReviewProposeCommand {
141
+ attemptId: string;
142
+ proposedStatus: DecisionStatus;
143
+ reason: string;
144
+ expiresAt?: string | null;
145
+ }
146
+ interface ReviewDecideCommand {
147
+ proposalId: string;
148
+ transition: Extract<GovernanceTransition, 'approve' | 'deny'>;
149
+ reason: string;
150
+ }
151
+ interface ReviewCaseTransitionCommand {
152
+ reviewCaseId: string;
153
+ transition: GovernanceTransition;
154
+ reason: string;
155
+ }
156
+ interface SafeAttemptView {
157
+ attemptId: string;
158
+ packageCode: VerificationPackageCode;
159
+ status: VerificationCanonicalStatus;
160
+ provider: VerificationProviderCode;
161
+ environment: VerificationProviderEnvironment;
162
+ adapterVersion: string;
163
+ manifestDigest: string;
164
+ configurationRevision: string;
165
+ policyVersion: string;
166
+ canResume: boolean;
167
+ canRetry: boolean;
168
+ expiresAt: string | null;
169
+ safeErrorCode: string | null;
170
+ retryAfter: string | null;
171
+ supportPath: string | null;
172
+ launch: ProviderLaunchEnvelope | null;
173
+ }
174
+ interface ProtectedActionAllow {
175
+ allowed: true;
176
+ }
177
+ type ProtectedActionResult = ProtectedActionAllow | ProtectedActionDenial;
178
+ interface TenantRecord {
179
+ tenantKey: string;
180
+ displayName: string;
181
+ continuationDestinations: string[];
182
+ createdAt: string;
183
+ }
184
+ interface ConfigurationRevisionRecord {
185
+ tenantKey: string;
186
+ id: string;
187
+ provider: VerificationProviderCode;
188
+ environment: VerificationProviderEnvironment;
189
+ revision: number;
190
+ configurationDigest: string;
191
+ lifecycle: 'draft' | 'approved' | 'retired';
192
+ proposedByActorId: string | null;
193
+ approvedByActorId: string | null;
194
+ approvedAt: string | null;
195
+ createdAt: string;
196
+ }
197
+ interface ProviderDefinitionRecord {
198
+ tenantKey: string;
199
+ provider: VerificationProviderCode;
200
+ environment: VerificationProviderEnvironment;
201
+ adapterVersion: string;
202
+ manifestDigest: string;
203
+ compiledInRegistry: boolean;
204
+ productionEligible: boolean;
205
+ createdAt: string;
206
+ updatedAt: string;
207
+ }
208
+ interface RouteRecord {
209
+ tenantKey: string;
210
+ id: string;
211
+ provider: VerificationProviderCode;
212
+ environment: VerificationProviderEnvironment;
213
+ packageCode: VerificationPackageCode;
214
+ countryCode: string | null;
215
+ requiredCapability: string | null;
216
+ priority: number;
217
+ cohortMin: number;
218
+ cohortMax: number;
219
+ windowStart: string | null;
220
+ windowEnd: string | null;
221
+ allowlistRequired: boolean;
222
+ allowlistedSubjectHashes: string[];
223
+ configurationRevisionId: string;
224
+ policyVersionId: string;
225
+ lifecycle: RouteLifecycle;
226
+ proposedByActorId: string | null;
227
+ approvedByActorId: string | null;
228
+ approvedAt: string | null;
229
+ activatedAt: string | null;
230
+ createdAt: string;
231
+ updatedAt: string;
232
+ }
233
+ interface RouteChangeRequestRecord {
234
+ tenantKey: string;
235
+ id: string;
236
+ routeId: string | null;
237
+ proposedPayload: Record<string, string | number | boolean | null>;
238
+ status: ProposalStatus;
239
+ reason: string;
240
+ policyVersion: string;
241
+ proposedByActorId: string;
242
+ approvedByActorId: string | null;
243
+ approvedAt: string | null;
244
+ expiresAt: string | null;
245
+ createdAt: string;
246
+ }
247
+ interface PolicyVersionRecord {
248
+ tenantKey: string;
249
+ id: string;
250
+ version: string;
251
+ environment: VerificationProviderEnvironment;
252
+ lifecycle: PolicyLifecycle;
253
+ reason: string;
254
+ expiresAt: string | null;
255
+ proposedByActorId: string | null;
256
+ approvedByActorId: string | null;
257
+ approvedAt: string | null;
258
+ activatedAt: string | null;
259
+ createdAt: string;
260
+ decisionRetentionDays: number | null;
261
+ providerRedactionDelayDays: number | null;
262
+ appealHoldDays: number | null;
263
+ legalHold: boolean;
264
+ }
265
+ interface ProtectedActionRequirementRecord {
266
+ tenantKey: string;
267
+ id: string;
268
+ action: string;
269
+ packageCode: VerificationPackageCode;
270
+ policyVersionId: string;
271
+ createdAt: string;
272
+ }
273
+ interface AttemptRecord {
274
+ tenantKey: string;
275
+ id: string;
276
+ subjectHash: string;
277
+ packageCode: VerificationPackageCode;
278
+ countryCode: string;
279
+ provider: VerificationProviderCode;
280
+ environment: VerificationProviderEnvironment;
281
+ adapterVersion: string;
282
+ manifestDigest: string;
283
+ configurationRevision: string;
284
+ policyVersion: string;
285
+ providerResourceId: string | null;
286
+ providerStatus: string | null;
287
+ canonicalStatus: VerificationCanonicalStatus;
288
+ statusVersion: number;
289
+ idempotencyKey: string;
290
+ parentAttemptId: string | null;
291
+ purposeAction: string | null;
292
+ purposeResourceHash: string | null;
293
+ routeId: string;
294
+ selectionReason: string;
295
+ normalizedReasonCodes: string[];
296
+ expiresAt: string | null;
297
+ createClaimId: string | null;
298
+ createClaimExpiresAt: string | null;
299
+ createdAt: string;
300
+ updatedAt: string;
301
+ }
302
+ interface ProviderResourceLineageRecord {
303
+ tenantKey: string;
304
+ id: string;
305
+ attemptId: string;
306
+ resourceType: string;
307
+ providerResourceId: string;
308
+ relationshipCode: string;
309
+ providerStatus: string;
310
+ occurredAt: string;
311
+ }
312
+ interface DecisionRecord {
313
+ tenantKey: string;
314
+ id: string;
315
+ subjectHash: string;
316
+ packageCode: VerificationPackageCode;
317
+ attemptId: string | null;
318
+ status: DecisionStatus;
319
+ source: 'provider' | 'manual';
320
+ policyVersion: string;
321
+ reasonCodes: string[];
322
+ effectiveAt: string;
323
+ expiresAt: string | null;
324
+ revokedAt: string | null;
325
+ proposerActorId: string | null;
326
+ approverActorId: string | null;
327
+ createdAt: string;
328
+ }
329
+ interface IdempotencyClaimRecord {
330
+ tenantKey: string;
331
+ claimKey: string;
332
+ operation: string;
333
+ attemptId: string | null;
334
+ state: IdempotencyState;
335
+ resultRef: string | null;
336
+ errorCode: string | null;
337
+ createdAt: string;
338
+ completedAt: string | null;
339
+ }
340
+ interface WebhookEventRecord {
341
+ tenantKey: string;
342
+ id: string;
343
+ provider: VerificationProviderCode;
344
+ providerEventKey: string;
345
+ providerResourceId: string;
346
+ eventType: string;
347
+ occurredAt: string;
348
+ bodySha256: string;
349
+ safeMetadata: Record<string, string | boolean | number | null>;
350
+ state: WebhookEventState;
351
+ receivedAt: string;
352
+ }
353
+ interface WebhookLeaseRecord {
354
+ tenantKey: string;
355
+ eventId: string;
356
+ leaseId: string | null;
357
+ workerId: string | null;
358
+ expiresAt: string | null;
359
+ attemptCount: number;
360
+ nextAttemptAt: string;
361
+ lastErrorCode: string | null;
362
+ }
363
+ interface JobRecord {
364
+ tenantKey: string;
365
+ id: string;
366
+ kind: QueueJobKind;
367
+ attemptId: string | null;
368
+ eventId: string | null;
369
+ subjectHash: string | null;
370
+ providerResourceId: string | null;
371
+ state: 'scheduled' | 'processing' | 'retryable' | 'completed' | 'dead_letter' | RedactionStatus;
372
+ leaseId: string | null;
373
+ leaseExpiresAt: string | null;
374
+ attemptCount: number;
375
+ nextAttemptAt: string;
376
+ lastErrorCode: string | null;
377
+ createdAt: string;
378
+ }
379
+ interface HealthObservationRecord {
380
+ tenantKey: string;
381
+ id: string;
382
+ provider: VerificationProviderCode;
383
+ environment: VerificationProviderEnvironment;
384
+ operation: string;
385
+ outcome: 'success' | 'retryable_failure' | 'terminal_failure' | 'unknown_status';
386
+ safeCode: string;
387
+ observedAt: string;
388
+ latencyMs: number | null;
389
+ }
390
+ interface CircuitRecord {
391
+ tenantKey: string;
392
+ provider: VerificationProviderCode;
393
+ environment: VerificationProviderEnvironment;
394
+ state: CircuitState;
395
+ reasonCode: string | null;
396
+ openUntil: string | null;
397
+ consecutiveFailures: number;
398
+ drainedByActorId: string | null;
399
+ updatedAt: string;
400
+ }
401
+ interface AppealRecord {
402
+ tenantKey: string;
403
+ id: string;
404
+ attemptId: string;
405
+ subjectHash: string;
406
+ status: AppealStatus;
407
+ reason: string;
408
+ policyVersion: string;
409
+ proposedByActorId: string;
410
+ decidedByActorId: string | null;
411
+ expiresAt: string | null;
412
+ createdAt: string;
413
+ updatedAt: string;
414
+ }
415
+ interface ReviewCaseRecord {
416
+ tenantKey: string;
417
+ id: string;
418
+ attemptId: string;
419
+ subjectHash: string;
420
+ status: ReviewStatus;
421
+ reason: string;
422
+ policyVersion: string;
423
+ assignedActorId: string | null;
424
+ createdAt: string;
425
+ updatedAt: string;
426
+ }
427
+ interface ManualDecisionProposalRecord {
428
+ tenantKey: string;
429
+ id: string;
430
+ reviewCaseId: string | null;
431
+ attemptId: string;
432
+ proposedStatus: DecisionStatus;
433
+ reason: string;
434
+ policyVersion: string;
435
+ expiresAt: string | null;
436
+ proposedByActorId: string;
437
+ approvedByActorId: string | null;
438
+ status: ProposalStatus;
439
+ createdAt: string;
440
+ }
441
+ interface ContinuationRecord {
442
+ tenantKey: string;
443
+ key: string;
444
+ tokenHash: string;
445
+ action: string;
446
+ resourceHash: string;
447
+ subjectHash: string;
448
+ destinationKey: string;
449
+ expiresAt: string;
450
+ consumedAt: string | null;
451
+ }
452
+ interface AuditEventRecord {
453
+ tenantKey: string;
454
+ id: string;
455
+ actorId: string;
456
+ actorType: ActorContext['actorType'];
457
+ operation: string;
458
+ resourceType: string;
459
+ resourceId: string | null;
460
+ reasonCode: string | null;
461
+ safeMetadata: Record<string, string | number | boolean | null>;
462
+ occurredAt: string;
463
+ }
464
+ interface WebhookClaimResult {
465
+ disposition: 'claimed' | 'duplicate' | 'mismatch' | 'in_progress' | 'dead_letter';
466
+ event: WebhookEventRecord;
467
+ }
468
+ interface IngestWebhookResult {
469
+ accepted: true;
470
+ duplicate: boolean;
471
+ eventId: string;
472
+ }
473
+ type RateAcquireResult = {
474
+ allowed: boolean;
475
+ retryAfterSeconds?: number;
476
+ };
477
+
478
+ interface PolicyStore {
479
+ getActivePolicy(tenantKey: string, environment: VerificationProviderEnvironment): Promise<PolicyVersionRecord | null>;
480
+ getPolicyVersion(tenantKey: string, id: string): Promise<PolicyVersionRecord | null>;
481
+ listPolicyVersions(tenantKey: string): Promise<PolicyVersionRecord[]>;
482
+ savePolicyVersion(policy: PolicyVersionRecord): Promise<void>;
483
+ listProtectedActionRequirements(tenantKey: string, action: string, policyVersionId: string): Promise<ProtectedActionRequirementRecord[]>;
484
+ saveProtectedActionRequirement(requirement: ProtectedActionRequirementRecord): Promise<void>;
485
+ getContinuationDestinations(tenantKey: string): Promise<string[]>;
486
+ }
487
+ interface VerificationStore extends PolicyStore {
488
+ now(): Date;
489
+ hashSubject(tenantKey: string, subjectReference: string): Promise<string>;
490
+ hashResource(tenantKey: string, resourceType: string, resourceReference: string): Promise<string>;
491
+ transact<T>(fn: (store: VerificationStore) => Promise<T>): Promise<T>;
492
+ getTenant(tenantKey: string): Promise<TenantRecord | null>;
493
+ ensureTenant(tenantKey: string, displayName?: string): Promise<TenantRecord>;
494
+ getConfigurationRevision(tenantKey: string, id: string): Promise<ConfigurationRevisionRecord | null>;
495
+ listConfigurationRevisions(tenantKey: string): Promise<ConfigurationRevisionRecord[]>;
496
+ saveConfigurationRevision(revision: ConfigurationRevisionRecord): Promise<void>;
497
+ upsertProviderDefinition(definition: ProviderDefinitionRecord): Promise<void>;
498
+ getProviderDefinition(tenantKey: string, provider: VerificationProviderCode, environment: VerificationProviderEnvironment): Promise<ProviderDefinitionRecord | null>;
499
+ listProviderDefinitions(tenantKey: string): Promise<ProviderDefinitionRecord[]>;
500
+ getRoute(tenantKey: string, routeId: string): Promise<RouteRecord | null>;
501
+ listRoutes(tenantKey: string): Promise<RouteRecord[]>;
502
+ listActiveRoutes(tenantKey: string, environment: VerificationProviderEnvironment): Promise<RouteRecord[]>;
503
+ saveRoute(route: RouteRecord): Promise<void>;
504
+ saveRouteChangeRequest(request: RouteChangeRequestRecord): Promise<void>;
505
+ getRouteChangeRequest(tenantKey: string, id: string): Promise<RouteChangeRequestRecord | null>;
506
+ listRouteChangeRequests(tenantKey: string): Promise<RouteChangeRequestRecord[]>;
507
+ getAttempt(tenantKey: string, attemptId: string): Promise<AttemptRecord | null>;
508
+ getAttemptByIdempotencyKey(tenantKey: string, key: string): Promise<AttemptRecord | null>;
509
+ findAttemptByProviderResource(tenantKey: string, provider: VerificationProviderCode, providerResourceId: string): Promise<AttemptRecord | null>;
510
+ listAttempts(tenantKey: string): Promise<AttemptRecord[]>;
511
+ listLiveAttempts(tenantKey: string, subjectHash: string, packageCode: VerificationPackageCode): Promise<AttemptRecord[]>;
512
+ insertAttempt(attempt: AttemptRecord): Promise<AttemptRecord>;
513
+ updateAttempt(attempt: AttemptRecord): Promise<void>;
514
+ insertLineage(row: ProviderResourceLineageRecord): Promise<void>;
515
+ listLineage(tenantKey: string, attemptId: string): Promise<ProviderResourceLineageRecord[]>;
516
+ getValidDecision(tenantKey: string, subjectHash: string, packageCode: VerificationPackageCode, at: Date): Promise<DecisionRecord | null>;
517
+ insertDecision(decision: DecisionRecord): Promise<void>;
518
+ listDecisions(tenantKey: string, subjectHash?: string): Promise<DecisionRecord[]>;
519
+ revokeDecision(tenantKey: string, decisionId: string, at: string): Promise<void>;
520
+ claimIdempotency(claim: IdempotencyClaimRecord): Promise<{
521
+ disposition: 'claimed' | 'existing';
522
+ claim: IdempotencyClaimRecord;
523
+ }>;
524
+ completeIdempotency(tenantKey: string, key: string, resultRef: string): Promise<void>;
525
+ failIdempotency(tenantKey: string, key: string, errorCode: string): Promise<void>;
526
+ getIdempotencyClaim(tenantKey: string, key: string): Promise<IdempotencyClaimRecord | null>;
527
+ claimWebhookEvent(input: {
528
+ tenantKey: string;
529
+ provider: VerificationProviderCode;
530
+ providerEventKey: string;
531
+ providerResourceId: string;
532
+ eventType: string;
533
+ occurredAt: string;
534
+ bodySha256: string;
535
+ safeMetadata: Record<string, string | boolean | number | null>;
536
+ }): Promise<WebhookClaimResult>;
537
+ getWebhookEvent(tenantKey: string, provider: VerificationProviderCode, eventKey: string): Promise<WebhookEventRecord | null>;
538
+ getWebhookEventById(tenantKey: string, eventId: string): Promise<WebhookEventRecord | null>;
539
+ settleWebhookEvent(tenantKey: string, eventId: string, outcome: 'completed' | 'retryable' | 'dead_letter', errorCode?: string): Promise<void>;
540
+ recordHealth(observation: HealthObservationRecord): Promise<void>;
541
+ listHealth(tenantKey: string, provider?: VerificationProviderCode): Promise<HealthObservationRecord[]>;
542
+ getCircuit(tenantKey: string, provider: VerificationProviderCode, environment: VerificationProviderEnvironment): Promise<CircuitRecord>;
543
+ saveCircuit(circuit: CircuitRecord): Promise<void>;
544
+ listCircuits(tenantKey: string): Promise<CircuitRecord[]>;
545
+ saveAppeal(appeal: AppealRecord): Promise<void>;
546
+ getAppeal(tenantKey: string, id: string): Promise<AppealRecord | null>;
547
+ listAppeals(tenantKey: string): Promise<AppealRecord[]>;
548
+ saveReviewCase(reviewCase: ReviewCaseRecord): Promise<void>;
549
+ getReviewCase(tenantKey: string, id: string): Promise<ReviewCaseRecord | null>;
550
+ listReviewCases(tenantKey: string): Promise<ReviewCaseRecord[]>;
551
+ saveManualDecisionProposal(proposal: ManualDecisionProposalRecord): Promise<void>;
552
+ getManualDecisionProposal(tenantKey: string, id: string): Promise<ManualDecisionProposalRecord | null>;
553
+ listManualDecisionProposals(tenantKey: string): Promise<ManualDecisionProposalRecord[]>;
554
+ saveContinuation(continuation: ContinuationRecord): Promise<void>;
555
+ getContinuation(tenantKey: string, key: string): Promise<ContinuationRecord | null>;
556
+ appendAudit(event: AuditEventRecord): Promise<void>;
557
+ listAudit(tenantKey: string): Promise<AuditEventRecord[]>;
558
+ saveJob(job: JobRecord): Promise<void>;
559
+ getJob(tenantKey: string, id: string): Promise<JobRecord | null>;
560
+ listJobs(tenantKey: string, kind?: QueueJobKind): Promise<JobRecord[]>;
561
+ claimJobs(input: {
562
+ tenantKey: string;
563
+ kinds: QueueJobKind[];
564
+ workerId: string;
565
+ leaseSeconds: number;
566
+ limit: number;
567
+ now: Date;
568
+ }): Promise<JobRecord[]>;
569
+ updateJob(job: JobRecord): Promise<void>;
570
+ updateRedactionStatus(tenantKey: string, jobId: string, status: RedactionStatus): Promise<void>;
571
+ }
572
+
573
+ interface MemoryStoreOptions {
574
+ hashSecret?: string;
575
+ now?: () => Date;
576
+ seedTenantKey?: string;
577
+ }
578
+ declare function createMemoryStore(options?: MemoryStoreOptions): VerificationStore & PolicyStore;
579
+
580
+ interface VerificationQueue {
581
+ enqueue(job: JobRecord): Promise<void>;
582
+ claim(input: {
583
+ tenantKey: string;
584
+ kinds: QueueJobKind[];
585
+ workerId: string;
586
+ leaseSeconds: number;
587
+ limit: number;
588
+ now: Date;
589
+ }): Promise<JobRecord[]>;
590
+ complete(tenantKey: string, jobId: string, leaseId: string): Promise<void>;
591
+ retry(tenantKey: string, jobId: string, leaseId: string, options: {
592
+ errorCode: string;
593
+ retryAfterSeconds: number;
594
+ deadLetter?: boolean;
595
+ }): Promise<void>;
596
+ }
597
+ declare function backoffSeconds(attemptCount: number, retryAfterSeconds?: number, random?: () => number): number;
598
+
599
+ declare function createMemoryQueue(store: VerificationStore, options?: {
600
+ random?: () => number;
601
+ }): VerificationQueue;
602
+
603
+ interface CreateVerificationPlatformInput {
604
+ registry: ProviderRegistry;
605
+ store: VerificationStore;
606
+ queue: VerificationQueue;
607
+ policyStore?: PolicyStore;
608
+ authorize: AuthorizeFn;
609
+ runtime?: EngineRuntime;
610
+ }
611
+ interface VerificationPlatform {
612
+ start(actor: ActorContext, command: StartVerificationCommand): Promise<SafeAttemptView>;
613
+ resume(actor: ActorContext, command: ResumeVerificationCommand): Promise<SafeAttemptView>;
614
+ status(actor: ActorContext, attemptId: string): Promise<SafeAttemptView>;
615
+ retry(actor: ActorContext, command: RetryVerificationCommand): Promise<SafeAttemptView>;
616
+ pause(actor: ActorContext, attemptId: string): Promise<SafeAttemptView>;
617
+ cancel(actor: ActorContext, attemptId: string): Promise<SafeAttemptView>;
618
+ redact(actor: ActorContext, command: RedactCommand): Promise<{
619
+ jobId: string;
620
+ status: string;
621
+ }>;
622
+ ingestWebhook(command: IngestWebhookCommand): Promise<IngestWebhookResult>;
623
+ processWebhookJob(tenantKey: string, job: JobRecord): Promise<void>;
624
+ reconcile(actor: ActorContext, attemptId?: string): Promise<{
625
+ reconciled: number;
626
+ }>;
627
+ appeal: {
628
+ submit(actor: ActorContext, command: AppealSubmitCommand): Promise<{
629
+ appealId: string;
630
+ }>;
631
+ transition(actor: ActorContext, command: AppealTransitionCommand): Promise<{
632
+ status: string;
633
+ }>;
634
+ };
635
+ review: {
636
+ propose(actor: ActorContext, command: ReviewProposeCommand): Promise<{
637
+ proposalId: string;
638
+ reviewCaseId: string;
639
+ }>;
640
+ decide(actor: ActorContext, command: ReviewDecideCommand): Promise<{
641
+ status: string;
642
+ }>;
643
+ transitionCase(actor: ActorContext, command: ReviewCaseTransitionCommand): Promise<{
644
+ status: string;
645
+ }>;
646
+ };
647
+ admin: {
648
+ health(actor: ActorContext): Promise<unknown>;
649
+ routes(actor: ActorContext): Promise<unknown>;
650
+ circuits(actor: ActorContext): Promise<unknown>;
651
+ attempts(actor: ActorContext): Promise<unknown>;
652
+ audit(actor: ActorContext): Promise<unknown>;
653
+ proposeRoute(actor: ActorContext, input: {
654
+ route: Omit<RouteRecord, 'lifecycle' | 'approvedByActorId' | 'approvedAt' | 'activatedAt'>;
655
+ reason: string;
656
+ }): Promise<{
657
+ requestId: string;
658
+ }>;
659
+ approveRoute(actor: ActorContext, requestId: string, reason: string): Promise<{
660
+ routeId: string;
661
+ }>;
662
+ proposePolicy(actor: ActorContext, input: {
663
+ version: string;
664
+ environment: 'sandbox' | 'production';
665
+ reason: string;
666
+ expiresAt?: string | null;
667
+ decisionRetentionDays?: number | null;
668
+ providerRedactionDelayDays?: number | null;
669
+ appealHoldDays?: number | null;
670
+ legalHold?: boolean;
671
+ }): Promise<{
672
+ policyId: string;
673
+ }>;
674
+ approvePolicy(actor: ActorContext, policyId: string, reason: string): Promise<{
675
+ policyId: string;
676
+ }>;
677
+ activatePolicy(actor: ActorContext, policyId: string): Promise<{
678
+ policyId: string;
679
+ }>;
680
+ emergencyDrain(actor: ActorContext, provider: string, environment: 'sandbox' | 'production', reason: string): Promise<{
681
+ state: string;
682
+ }>;
683
+ };
684
+ evaluateProtectedAction(actor: ActorContext, command: ProtectedActionCommand): Promise<ProtectedActionResult>;
685
+ workers: {
686
+ claim(actor: ActorContext, input?: {
687
+ workerId?: string;
688
+ kinds?: JobRecord['kind'][];
689
+ limit?: number;
690
+ }): Promise<JobRecord[]>;
691
+ process(actor: ActorContext, job: JobRecord | {
692
+ id: string;
693
+ }): Promise<{
694
+ processed: boolean;
695
+ disposition: string;
696
+ }>;
697
+ scheduleReconciliation(actor: ActorContext): Promise<{
698
+ enqueued: number;
699
+ }>;
700
+ };
701
+ }
702
+ declare function createVerificationPlatform(input: CreateVerificationPlatformInput): VerificationPlatform;
703
+
704
+ interface RateBudget {
705
+ consume(provider: string, at?: Date): {
706
+ allowed: boolean;
707
+ retryAfterSeconds?: number;
708
+ };
709
+ }
710
+ declare function createRateBudget(limitPerSecond: number): RateBudget;
711
+
712
+ declare function seedSandboxExamples(store: VerificationStore, registry: ProviderRegistry, runtime: EngineRuntime, tenantKey?: string): Promise<void>;
713
+
714
+ interface RouteSelection {
715
+ route: RouteRecord;
716
+ adapter: VerificationAdapterV1;
717
+ reason: string;
718
+ usedFailover: boolean;
719
+ }
720
+ declare function selectRoute(input: {
721
+ store: VerificationStore;
722
+ adapters: VerificationAdapterV1[];
723
+ tenantKey: string;
724
+ packageCode: VerificationPackageCode;
725
+ countryCode: string;
726
+ subjectHash: string;
727
+ environment: VerificationProviderEnvironment;
728
+ runtime: EngineRuntime;
729
+ requiredCapability?: 'canResume' | 'canRetry' | 'canCancel' | 'canRedact' | null;
730
+ }): Promise<RouteSelection>;
731
+
732
+ declare function canTransitionStatus(current: VerificationCanonicalStatus, next: VerificationCanonicalStatus): boolean;
733
+ declare function applyMonotonicStatus(current: VerificationCanonicalStatus, next: VerificationCanonicalStatus): VerificationCanonicalStatus;
734
+
735
+ declare function assertNoClientRouting(command: object): void;
736
+
737
+ export { APPLICATION_REASON_CODES, type AppealRecord, type AppealStatus, type AppealSubmitCommand, type AppealTransitionCommand, type ApplicationReasonCode, type AttemptRecord, type AuditEventRecord, AuthorizationError, type AuthorizeFn, type CircuitRecord, type CircuitState, ClientRouteInjectionError, type ConfigurationRevisionRecord, type ContinuationRecord, type CreateVerificationPlatformInput, type DecisionRecord, type DecisionStatus, EngineError, type EngineErrorCode, type EngineOperation, type EngineRuntime, FORBIDDEN_CLIENT_ROUTE_KEYS, GOVERNANCE_TRANSITIONS, type GovernanceTransition, type HealthObservationRecord, type IdempotencyClaimRecord, type IdempotencyState, type IngestWebhookCommand, type IngestWebhookResult, type JobRecord, LIVE_ATTEMPT_STATUSES, type ManualDecisionProposalRecord, type PolicyLifecycle, type PolicyStore, type PolicyVersionRecord, type ProposalStatus, type ProtectedActionAllow, type ProtectedActionCommand, type ProtectedActionRequirementRecord, type ProtectedActionResult, type ProviderDefinitionRecord, type ProviderRegistry, type ProviderResourceLineageRecord, type QueueJobKind, type RateAcquireResult, type RateBudget, type RedactCommand, type RedactionStatus, type ResumeVerificationCommand, type RetryVerificationCommand, type ReviewCaseRecord, type ReviewCaseTransitionCommand, type ReviewDecideCommand, type ReviewProposeCommand, type ReviewStatus, type RouteChangeRequestRecord, type RouteLifecycle, type RouteRecord, type SafeAttemptView, type StartVerificationCommand, type TenantRecord, type VerificationPlatform, type VerificationQueue, type VerificationStore, type WebhookClaimResult, type WebhookEventRecord, type WebhookEventState, type WebhookLeaseRecord, WebhookSecurityIncidentError, applyMonotonicStatus, assertNoClientRouting, backoffSeconds, canTransitionStatus, canonicalize, cohortBucket, createMemoryQueue, createMemoryStore, createProviderRegistry, createRateBudget, createVerificationPlatform, digestCanonical, hmacSha256Hex, isApplicationReasonCode, seedSandboxExamples, selectRoute, sha256Hex };