@fabricorg/platform-host 8.8.0 → 8.9.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/CHANGELOG.md +321 -0
- package/README.md +760 -9
- package/dist/index.cjs +6239 -393
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +560 -36
- package/dist/index.d.ts +560 -36
- package/dist/index.js +6220 -398
- package/dist/index.js.map +1 -1
- package/package.json +5 -5
package/dist/index.d.cts
CHANGED
|
@@ -203,30 +203,60 @@ export declare class IdempotencyConflictError extends Error {
|
|
|
203
203
|
export type ActionAdmissionRefusal = "refused" | "failed" | "timed_out" | "invalid_decision" | "invalid_parameters";
|
|
204
204
|
/**
|
|
205
205
|
* Thrown by `submitAction` when a declared admission check did not admit the
|
|
206
|
-
* submission. Host
|
|
207
|
-
*
|
|
208
|
-
*
|
|
209
|
-
*
|
|
206
|
+
* submission. By default Host writes nothing for it. With recordRefusals
|
|
207
|
+
* enabled and an idempotency key, a definitive refusal can be recorded;
|
|
208
|
+
* `recorded` confirms persistence of the terminal refusal. The message holds
|
|
209
|
+
* the action id, the refusal and, for `refused`, the check's fixed code. It omits parameter
|
|
210
|
+
* payloads and caught callback error text.
|
|
210
211
|
*/
|
|
211
212
|
export declare class ActionAdmissionError extends Error {
|
|
212
213
|
readonly actionId: string;
|
|
213
214
|
readonly refusal: ActionAdmissionRefusal;
|
|
214
215
|
/** The check's own code, present only for `refused`. */
|
|
215
216
|
readonly refusalCode?: string | undefined;
|
|
217
|
+
readonly recorded: boolean;
|
|
216
218
|
readonly code: "ACTION_ADMISSION_REFUSED";
|
|
217
219
|
constructor(actionId: string, refusal: ActionAdmissionRefusal,
|
|
218
220
|
/** The check's own code, present only for `refused`. */
|
|
219
|
-
refusalCode?: string | undefined);
|
|
221
|
+
refusalCode?: string | undefined, recorded?: boolean);
|
|
220
222
|
}
|
|
221
223
|
export type SubmissionRefusal = "entitlement" | "authorization";
|
|
222
224
|
/** A definitive authorization-boundary refusal before an invocation is created. */
|
|
223
225
|
export declare class SubmissionRefusalError extends Error {
|
|
224
226
|
readonly actionId: string;
|
|
225
227
|
readonly refusal: SubmissionRefusal;
|
|
228
|
+
readonly recorded: boolean;
|
|
226
229
|
readonly code: "ACTION_SUBMISSION_REFUSED";
|
|
227
|
-
constructor(actionId: string, refusal: SubmissionRefusal, message: string);
|
|
230
|
+
constructor(actionId: string, refusal: SubmissionRefusal, message: string, recorded?: boolean);
|
|
228
231
|
}
|
|
229
|
-
|
|
232
|
+
/** Fixed refusal evidence; no submitted values belong in a descriptor. */
|
|
233
|
+
export type SubmissionRefusalDescriptor = {
|
|
234
|
+
class: "entitlement" | "authorization";
|
|
235
|
+
} | {
|
|
236
|
+
class: "admission";
|
|
237
|
+
refusal: "refused" | "invalid_parameters";
|
|
238
|
+
refusalCode?: string;
|
|
239
|
+
};
|
|
240
|
+
/** Minimal identity and evidence for an insert-only, terminal refusal. */
|
|
241
|
+
export interface RecordSubmissionRefusalInput {
|
|
242
|
+
id: string;
|
|
243
|
+
tenantId: string;
|
|
244
|
+
spaceId: string;
|
|
245
|
+
actionId: ActionId;
|
|
246
|
+
actionVersion: number;
|
|
247
|
+
actorId: string;
|
|
248
|
+
actorType: ActorType;
|
|
249
|
+
authorizationBindingId?: string;
|
|
250
|
+
idempotencyKey: string;
|
|
251
|
+
submissionRefusal: SubmissionRefusalDescriptor;
|
|
252
|
+
parameterDigest?: string;
|
|
253
|
+
parameterDigestAlgorithm?: "fabric-canonical-json-sha256-v1";
|
|
254
|
+
correlationId: string;
|
|
255
|
+
causationId?: string;
|
|
256
|
+
createdAt: Date;
|
|
257
|
+
updatedAt: Date;
|
|
258
|
+
}
|
|
259
|
+
export type ExternalCompletionRefusal = "erased" | "still_executing" | "not_found" | "not_awaiting" | "immediate_contract" | "reference_mismatch" | "provider_mismatch" | "invalid_completion" | "result_invalid" | "redaction_failed";
|
|
230
260
|
/**
|
|
231
261
|
* Why a completion was not applied, typed so a webhook handler can answer
|
|
232
262
|
* the external system correctly: `retryable` means the invocation is still
|
|
@@ -292,6 +322,9 @@ export interface HostHitlEvaluatorContext extends AgentActionPolicyContext {
|
|
|
292
322
|
invocation: Readonly<ActionInvocationRecord>;
|
|
293
323
|
}
|
|
294
324
|
export interface ActionInvocationRecord {
|
|
325
|
+
/** Store-owned erasure marker; callers cannot patch it through Host write types. */
|
|
326
|
+
readonly storedRecordsErased?: true;
|
|
327
|
+
submissionRefusal?: SubmissionRefusalDescriptor;
|
|
295
328
|
readonly agentProposal?: AgentProposal;
|
|
296
329
|
id: string;
|
|
297
330
|
tenantId: string;
|
|
@@ -342,7 +375,7 @@ export interface ActionInvocationRecord {
|
|
|
342
375
|
externalCompletion?: RecordedExternalCompletion;
|
|
343
376
|
/** Opaque, non-secret reference used to revalidate delegated execution authority. */
|
|
344
377
|
authorizationBindingId?: string;
|
|
345
|
-
/** Worker claims including the first; approval acceptance sets a minimum of 1. */
|
|
378
|
+
/** Worker claims including the first; inline approval acceptance sets a minimum of 1. Recording preserves the count. */
|
|
346
379
|
attemptCount: number;
|
|
347
380
|
/** Latest claim durably deferred in pre-effect governance; permits only the immediately next claim. */
|
|
348
381
|
deferredBeforeEffectAttempt?: number;
|
|
@@ -405,6 +438,7 @@ export declare const MAX_APPROVAL_EVIDENCE_BYTES: number;
|
|
|
405
438
|
export declare const APPROVAL_REQUESTED_EVENT: "ApprovalRequested";
|
|
406
439
|
export declare const APPROVAL_DECIDED_EVENT: "ApprovalDecided";
|
|
407
440
|
export declare const APPROVAL_EXPIRED_EVENT: "ApprovalExpired";
|
|
441
|
+
export declare const APPROVAL_DECISION_REFUSED_EVENT: "ApprovalDecisionRefused";
|
|
408
442
|
export interface ApprovalRequestedPayload {
|
|
409
443
|
route: AgentActionRoute;
|
|
410
444
|
riskTier: AgentActionRiskTier;
|
|
@@ -435,6 +469,10 @@ export interface ActionApprovalDecision {
|
|
|
435
469
|
}
|
|
436
470
|
export interface PersistedActionApprovalDecision extends Omit<ActionApprovalDecision, "decidedAt"> {
|
|
437
471
|
decidedAt: Date;
|
|
472
|
+
/** Caller-stable identity for the separate recording API; absent on inline and older decisions. */
|
|
473
|
+
requestId?: string;
|
|
474
|
+
/** Claim count when recorded; the next claim is the approved first execution. */
|
|
475
|
+
recordedAtAttempt?: number;
|
|
438
476
|
}
|
|
439
477
|
export interface PolicyEvaluationRecord {
|
|
440
478
|
id: string;
|
|
@@ -554,7 +592,7 @@ export interface AdapterInvocationRecord {
|
|
|
554
592
|
createdAt: Date;
|
|
555
593
|
updatedAt: Date;
|
|
556
594
|
}
|
|
557
|
-
export interface CreateActionInvocationInput extends Omit<ActionInvocationRecord, "createdAt" | "updatedAt" | "attemptCount" | "leaseOwner" | "leaseExpiresAt" | "leaseToken" | "stagedOrigin"> {}
|
|
595
|
+
export interface CreateActionInvocationInput extends Omit<ActionInvocationRecord, "createdAt" | "updatedAt" | "attemptCount" | "leaseOwner" | "leaseExpiresAt" | "leaseToken" | "stagedOrigin" | "storedRecordsErased"> {}
|
|
558
596
|
/** Scope of an adapter checkpoint within its owning action invocation. */
|
|
559
597
|
export interface AdapterInvocationScope {
|
|
560
598
|
tenantId: string;
|
|
@@ -610,7 +648,17 @@ export interface PlatformHostStore<TDb> {
|
|
|
610
648
|
* canonical events, and invocation state must commit atomically.
|
|
611
649
|
*/
|
|
612
650
|
transaction<TResult>(run: (db: TDb) => Promise<TResult>): Promise<TResult>;
|
|
651
|
+
/**
|
|
652
|
+
* First row wins for a supplied idempotency key within tenant, space and action id,
|
|
653
|
+
* including the empty-string key. Replays return the existing row unchanged;
|
|
654
|
+
* the store does not classify submission conflicts (Host does). Unkeyed creates
|
|
655
|
+
* with distinct ids insert independently. `invocationIdempotencyChecks` also
|
|
656
|
+
* covers concurrent key arbitration and preservation of `admittedAt` through
|
|
657
|
+
* an update of another field, plus refusal/admitted arbitration when supported.
|
|
658
|
+
*/
|
|
613
659
|
createActionInvocation(input: CreateActionInvocationInput): Promise<ActionInvocationRecord>;
|
|
660
|
+
/** Insert a refusal or return the key's existing winner unchanged. */
|
|
661
|
+
recordSubmissionRefusal?(input: RecordSubmissionRefusalInput): Promise<ActionInvocationRecord>;
|
|
614
662
|
getActionInvocation(id: string, tenantId: string, spaceId: string): Promise<ActionInvocationRecord | undefined>;
|
|
615
663
|
/** Resolve Host-owned staged identity within one tenant and space. */
|
|
616
664
|
getActionInvocationByStagedOrigin?(tenantId: string, spaceId: string, origin: StagedInvocationOrigin): Promise<ActionInvocationRecord | undefined>;
|
|
@@ -684,8 +732,10 @@ export interface PlatformHostStore<TDb> {
|
|
|
684
732
|
* back when `run` throws.
|
|
685
733
|
*/
|
|
686
734
|
export interface PlatformHostMutationTransaction<TDb> {
|
|
735
|
+
/** Lock due approval candidates in this transaction, skipping locked invocation rows. */
|
|
736
|
+
lockDueApprovals?(input: ExpireDueApprovalsStoreInput): Promise<ActionInvocationRecord[]>;
|
|
687
737
|
/** Conditional SQL approval write on the transaction connection; lifecycle events are appended by the caller in this unit of work. */
|
|
688
|
-
beginApprovalDecision?(input: Omit<BeginApprovalDecisionInput
|
|
738
|
+
beginApprovalDecision?(input: Omit<BeginApprovalDecisionInput<TDb>, "lifecycleEvent">): Promise<ApprovalDecisionTransitionResult>;
|
|
689
739
|
readonly db: TDb;
|
|
690
740
|
/**
|
|
691
741
|
* Read and lock an invocation until this transaction completes.
|
|
@@ -694,9 +744,12 @@ export interface PlatformHostMutationTransaction<TDb> {
|
|
|
694
744
|
getActionInvocationForUpdate?(id: string, tenantId: string, spaceId: string): Promise<ActionInvocationRecord | undefined>;
|
|
695
745
|
/**
|
|
696
746
|
* Read one event by its stable identity inside the transaction.
|
|
747
|
+
* Erasure-capable stores expose storedRecordsErased on rewritten events.
|
|
697
748
|
* Required by serialized saga parent lifecycle transitions.
|
|
698
749
|
*/
|
|
699
|
-
getEvent?(id: string, tenantId: string, spaceId: string): Promise<AssetEventEnvelope
|
|
750
|
+
getEvent?(id: string, tenantId: string, spaceId: string): Promise<(AssetEventEnvelope & {
|
|
751
|
+
readonly storedRecordsErased?: true;
|
|
752
|
+
}) | undefined>;
|
|
700
753
|
/**
|
|
701
754
|
* First-write-wins: an event ID the store already holds, in any tenant or space, is a no-op
|
|
702
755
|
* that keeps the first event. Do not throw, replace or merge it, regardless of
|
|
@@ -747,7 +800,7 @@ export interface PlatformHostMutationTransaction<TDb> {
|
|
|
747
800
|
* governance evidence cannot share the event/verdict transaction.
|
|
748
801
|
*/
|
|
749
802
|
appendExternalReconciliation?: GovernancePlatformHostStore<TDb>["appendExternalReconciliation"];
|
|
750
|
-
/** Atomically retain
|
|
803
|
+
/** Atomically retain a staged batch with the parent mutation; erasure may later rewrite its payloads. */
|
|
751
804
|
stageInvocations?(records: readonly StagedInvocationRecord[]): Promise<void>;
|
|
752
805
|
}
|
|
753
806
|
export type StagedInvocationStatus = "pending" | "dispatched" | "rejected" | "dead_lettered" | "cancelled";
|
|
@@ -970,8 +1023,31 @@ export interface OutboxPlatformHostStore<TDb> extends PlatformHostStore<TDb> {
|
|
|
970
1023
|
* sequences and timestamps and potentially different payloads.
|
|
971
1024
|
*/
|
|
972
1025
|
appendEventWithOutbox(event: AssetEventEnvelope, metadata: OutboxEventMetadata): Promise<void>;
|
|
1026
|
+
/**
|
|
1027
|
+
* `outboxRelayChecks`: claim pending rows available at or before `now` with no
|
|
1028
|
+
* unexpired lease; equality at lease expiry is claimable. Concurrent workers
|
|
1029
|
+
* claim a row once between them. A claim sets owner and expiry to the worker
|
|
1030
|
+
* and `now + leaseDurationMs`, increments attempts by one and increases the
|
|
1031
|
+
* row's token. `limit: 1` returns one row when eligible rows exist.
|
|
1032
|
+
* Published and dead-lettered rows are excluded; returned ordering is unspecified.
|
|
1033
|
+
* `outboxRelayChecks` requires numeric lease tokens that increase on each claim,
|
|
1034
|
+
* including reclaim, despite the optional token fields in the general interfaces.
|
|
1035
|
+
*/
|
|
973
1036
|
claimOutbox(input: ClaimOutboxInput): Promise<OutboxRecord[]>;
|
|
1037
|
+
/**
|
|
1038
|
+
* `outboxRelayChecks`: reject a stale token after reclaim or a wrong worker
|
|
1039
|
+
* without changing the row. With the current owner/token, set `published`
|
|
1040
|
+
* and `publishedAt` and clear lease owner/expiry. A previously settled row
|
|
1041
|
+
* rejects another settlement under its former owner/token.
|
|
1042
|
+
*/
|
|
974
1043
|
markOutboxPublished(id: string, workerId: string, publishedAt: Date, leaseToken?: number): Promise<void>;
|
|
1044
|
+
/**
|
|
1045
|
+
* `outboxRelayChecks`: reject a stale token after reclaim or a wrong worker
|
|
1046
|
+
* without changing the row. With the current owner/token, set `pending` and
|
|
1047
|
+
* the supplied `availableAt`, clear lease owner/expiry and retain attempts;
|
|
1048
|
+
* `deadLetter: true` sets `dead_letter`. A previously settled row rejects
|
|
1049
|
+
* another settlement under its former owner/token.
|
|
1050
|
+
*/
|
|
975
1051
|
markOutboxFailed(input: {
|
|
976
1052
|
id: string;
|
|
977
1053
|
workerId: string;
|
|
@@ -980,6 +1056,13 @@ export interface OutboxPlatformHostStore<TDb> extends PlatformHostStore<TDb> {
|
|
|
980
1056
|
availableAt: Date;
|
|
981
1057
|
deadLetter: boolean;
|
|
982
1058
|
}): Promise<void>;
|
|
1059
|
+
/**
|
|
1060
|
+
* `outboxRelayChecks`: return false for a wrong worker/token or a lease expired
|
|
1061
|
+
* at or before `now`, leaving expiry unchanged. For the current unexpired
|
|
1062
|
+
* owner/token, return true and set expiry to `now + leaseDurationMs`.
|
|
1063
|
+
* When `renewOutboxLeaseAndRead` is present, the same probes expect undefined
|
|
1064
|
+
* on refusal and the renewed record on success.
|
|
1065
|
+
*/
|
|
983
1066
|
renewOutboxLease(input: {
|
|
984
1067
|
id: string;
|
|
985
1068
|
workerId: string;
|
|
@@ -987,6 +1070,14 @@ export interface OutboxPlatformHostStore<TDb> extends PlatformHostStore<TDb> {
|
|
|
987
1070
|
leaseDurationMs: number;
|
|
988
1071
|
now?: Date;
|
|
989
1072
|
}): Promise<boolean>;
|
|
1073
|
+
/** Renew and hydrate the stored envelope atomically for erasure-safe publication. */
|
|
1074
|
+
renewOutboxLeaseAndRead?(input: {
|
|
1075
|
+
id: string;
|
|
1076
|
+
workerId: string;
|
|
1077
|
+
leaseToken: number;
|
|
1078
|
+
leaseDurationMs: number;
|
|
1079
|
+
now?: Date;
|
|
1080
|
+
}): Promise<OutboxRecord | undefined>;
|
|
990
1081
|
listOutbox(input?: {
|
|
991
1082
|
tenantId?: string;
|
|
992
1083
|
spaceId?: string;
|
|
@@ -1120,6 +1211,15 @@ export interface OutboxRequeueAuthorizationInput {
|
|
|
1120
1211
|
* but cannot claim atomic domain-write/event persistence.
|
|
1121
1212
|
*/
|
|
1122
1213
|
export interface AtomicMutationPlatformHostStore<TDb> extends PlatformHostStore<TDb> {
|
|
1214
|
+
/**
|
|
1215
|
+
* Optional retry evidence: reject with ConfirmedTransactionRollback(callbackError)
|
|
1216
|
+
* after rollback succeeds. Its cause must be the identical callback error. A provider
|
|
1217
|
+
* that does not supply this evidence retains the existing failure behavior.
|
|
1218
|
+
* A commit error is not evidence that the callback rolled back. Built-in stores
|
|
1219
|
+
* expose evidence for Host's internal handler callback request; ordinary public
|
|
1220
|
+
* callbacks and store-internal transactions retain their original error objects.
|
|
1221
|
+
* Host normalizes confirmation from custom stores at non-handler transaction sites.
|
|
1222
|
+
*/
|
|
1123
1223
|
transactionWithEvents<TResult>(run: (transaction: PlatformHostMutationTransaction<TDb>) => Promise<TResult>): Promise<TResult>;
|
|
1124
1224
|
}
|
|
1125
1225
|
export interface ApprovalLifecycleEvent {
|
|
@@ -1128,6 +1228,50 @@ export interface ApprovalLifecycleEvent {
|
|
|
1128
1228
|
}
|
|
1129
1229
|
/** Called within the transition transaction. Must be pure and return audit-safe data. Sequence is assigned by the store. */
|
|
1130
1230
|
export type ApprovalLifecycleEventFactory = (invocation: ActionInvocationRecord, kind: "requested" | "decided" | "expired") => ApprovalLifecycleEvent;
|
|
1231
|
+
export interface RecordApprovalDecisionRequest extends ActionApprovalDecision {
|
|
1232
|
+
/** Non-blank caller-stable identifier, at most 256 characters; not trimmed or regenerated by Host. */
|
|
1233
|
+
requestId: string;
|
|
1234
|
+
}
|
|
1235
|
+
export type RecordApprovalDecisionOutcome = "approved" | "denied" | "unauthorized" | "expired" | "already_decided" | "late_terminal" | "not_waiting" | "unsupported";
|
|
1236
|
+
export interface RecordApprovalDecisionResult {
|
|
1237
|
+
outcome: RecordApprovalDecisionOutcome;
|
|
1238
|
+
actionInvocationId: string;
|
|
1239
|
+
status: ActionInvocationRecord["status"];
|
|
1240
|
+
replayed: boolean;
|
|
1241
|
+
/** Included for approved/denied outcomes, including replays; omitted for non-applied outcomes. */
|
|
1242
|
+
decision?: PersistedActionApprovalDecision;
|
|
1243
|
+
}
|
|
1244
|
+
export interface TransactionalApprovalAuthorization<TDb = unknown> {
|
|
1245
|
+
(db: TDb, invocation: Readonly<ActionInvocationRecord>): Promise<boolean>;
|
|
1246
|
+
}
|
|
1247
|
+
export interface RecordApprovalDecisionStoreInput<TDb = unknown> {
|
|
1248
|
+
actionInvocationId: string;
|
|
1249
|
+
tenantId: string;
|
|
1250
|
+
spaceId: string;
|
|
1251
|
+
now: Date;
|
|
1252
|
+
/** Carries no `recordedAtAttempt`: the store assigns it from the locked row. */
|
|
1253
|
+
decision: Omit<PersistedActionApprovalDecision, "recordedAtAttempt"> & {
|
|
1254
|
+
requestId: string;
|
|
1255
|
+
};
|
|
1256
|
+
/** Result of the compatibility authorization boundary evaluated before the transaction. */
|
|
1257
|
+
authorized: boolean;
|
|
1258
|
+
/**
|
|
1259
|
+
* Optional authority check on this transaction's `db`, after the invocation row is locked
|
|
1260
|
+
* and classified as writable, immediately before the decision write.
|
|
1261
|
+
*/
|
|
1262
|
+
authorizeInTransaction?: TransactionalApprovalAuthorization<TDb>;
|
|
1263
|
+
actionKind: "atomic" | "saga" | "unknown";
|
|
1264
|
+
lifecycleEvent?: ApprovalLifecycleEventFactory;
|
|
1265
|
+
/** Called under the invocation lock after any update, with the pre-patch observed row. */
|
|
1266
|
+
attemptEvent?: (invocation: ActionInvocationRecord, outcome: RecordApprovalDecisionOutcome) => ApprovalLifecycleEvent;
|
|
1267
|
+
}
|
|
1268
|
+
export interface RecordApprovalDecisionStoreResult {
|
|
1269
|
+
/** Whether this transaction changed the invocation; false for replays and previously expired rows. */
|
|
1270
|
+
applied: boolean;
|
|
1271
|
+
outcome: RecordApprovalDecisionOutcome;
|
|
1272
|
+
invocation: ActionInvocationRecord;
|
|
1273
|
+
replayed: boolean;
|
|
1274
|
+
}
|
|
1131
1275
|
export interface ExpireDueApprovalsInput {
|
|
1132
1276
|
tenantId?: string;
|
|
1133
1277
|
spaceId?: string;
|
|
@@ -1148,7 +1292,7 @@ export interface ParkApprovalInput {
|
|
|
1148
1292
|
leaseToken?: number;
|
|
1149
1293
|
lifecycleEvent?: ApprovalLifecycleEventFactory;
|
|
1150
1294
|
}
|
|
1151
|
-
export interface BeginApprovalDecisionInput {
|
|
1295
|
+
export interface BeginApprovalDecisionInput<TDb = unknown> {
|
|
1152
1296
|
lifecycleEvent?: ApprovalLifecycleEventFactory;
|
|
1153
1297
|
actionInvocationId: string;
|
|
1154
1298
|
tenantId: string;
|
|
@@ -1157,15 +1301,26 @@ export interface BeginApprovalDecisionInput {
|
|
|
1157
1301
|
leaseOwner: string;
|
|
1158
1302
|
leaseDurationMs: number;
|
|
1159
1303
|
now: Date;
|
|
1304
|
+
/**
|
|
1305
|
+
* Optional authority check on this transaction's `db`, after the invocation row is locked
|
|
1306
|
+
* and classified as writable, immediately before the decision write.
|
|
1307
|
+
*/
|
|
1308
|
+
authorizeInTransaction?: TransactionalApprovalAuthorization<TDb>;
|
|
1160
1309
|
}
|
|
1161
1310
|
export interface ApprovalDecisionTransitionResult {
|
|
1162
1311
|
applied: boolean;
|
|
1163
1312
|
invocation?: ActionInvocationRecord;
|
|
1313
|
+
/** True when a configured in-transaction authority check refused the decision. */
|
|
1314
|
+
authorizationDenied?: boolean;
|
|
1164
1315
|
}
|
|
1165
|
-
/**
|
|
1316
|
+
/** Approval persistence capabilities used by Host HITL, inline resume and decision recording. */
|
|
1166
1317
|
export interface ApprovalPlatformHostStore<TDb> extends PlatformHostStore<TDb> {
|
|
1318
|
+
/** Serialize classification, optional events/outbox and the queued/terminal transition in one transaction. */
|
|
1319
|
+
recordApprovalDecision?(input: RecordApprovalDecisionStoreInput<TDb>): Promise<RecordApprovalDecisionStoreResult>;
|
|
1167
1320
|
/** True only when approval transitions and lifecycle outbox events share a transaction. */
|
|
1168
1321
|
readonly transactionalApprovalLifecycle?: boolean;
|
|
1322
|
+
/** True only when approval authority callbacks run under the locked row in the decision transaction. */
|
|
1323
|
+
readonly transactionalApprovalAuthorization?: boolean;
|
|
1169
1324
|
/**
|
|
1170
1325
|
* Conditionally park an executable invocation only with its matching lease owner/generation
|
|
1171
1326
|
* (when leased) and no prior approval decision. Persist the deadline supplied in input.
|
|
@@ -1195,7 +1350,7 @@ export interface ApprovalPlatformHostStore<TDb> extends PlatformHostStore<TDb> {
|
|
|
1195
1350
|
* or expired event/outbox writes and state change must commit in the same atomic unit
|
|
1196
1351
|
* of work, or roll back together. Required when implementing parkApproval/expireDueApprovals.
|
|
1197
1352
|
*/
|
|
1198
|
-
beginApprovalDecision(input: BeginApprovalDecisionInput): Promise<ApprovalDecisionTransitionResult>;
|
|
1353
|
+
beginApprovalDecision(input: BeginApprovalDecisionInput<TDb>): Promise<ApprovalDecisionTransitionResult>;
|
|
1199
1354
|
}
|
|
1200
1355
|
/** Optional durable capabilities used when external-governance enrichment is configured. */
|
|
1201
1356
|
export interface GovernancePlatformHostStore<TDb> extends PlatformHostStore<TDb> {
|
|
@@ -1294,6 +1449,10 @@ export interface ActionExecutionAuthorizationInput extends ActionAuthorizationIn
|
|
|
1294
1449
|
invocation: Readonly<ActionInvocationRecord>;
|
|
1295
1450
|
executionReason: ActionExecutionReason;
|
|
1296
1451
|
}
|
|
1452
|
+
/** Execution authorization input evaluated on the handler transaction's domain handle. */
|
|
1453
|
+
export interface ActionExecutionAuthorizationInTransactionInput<TDb> extends ActionExecutionAuthorizationInput {
|
|
1454
|
+
db: TDb;
|
|
1455
|
+
}
|
|
1297
1456
|
/** Trusted authorization input for deciding a parked approval. */
|
|
1298
1457
|
export interface ActionApprovalAuthorizationInput extends ActionAuthorizationInput {
|
|
1299
1458
|
decision: ActionApprovalDecision;
|
|
@@ -1302,6 +1461,10 @@ export interface ActionApprovalAuthorizationInput extends ActionAuthorizationInp
|
|
|
1302
1461
|
/** The durable (post-redaction) invocation record as read before the decision transition. */
|
|
1303
1462
|
invocation: Readonly<ActionInvocationRecord>;
|
|
1304
1463
|
}
|
|
1464
|
+
/** Approval authorization input evaluated while the invocation row is locked for its decision write. */
|
|
1465
|
+
export interface ActionApprovalAuthorizationInTransactionInput<TDb> extends ActionApprovalAuthorizationInput {
|
|
1466
|
+
db: TDb;
|
|
1467
|
+
}
|
|
1305
1468
|
/**
|
|
1306
1469
|
* Input to `resolvePolicies`. Carries the invocation identity and the
|
|
1307
1470
|
* schema-parsed durable (post-redaction) parameters so a resolver can choose
|
|
@@ -1312,7 +1475,7 @@ export interface ActionApprovalAuthorizationInput extends ActionAuthorizationInp
|
|
|
1312
1475
|
export interface ResolvePoliciesInput extends ActionExecutionAuthorizationInput {
|
|
1313
1476
|
declaredPolicyIds: readonly string[];
|
|
1314
1477
|
}
|
|
1315
|
-
export interface PlatformHostAuthorization {
|
|
1478
|
+
export interface PlatformHostAuthorization<TDb = unknown> {
|
|
1316
1479
|
checkEntitlement(input: ActionAuthorizationInput): Promise<boolean>;
|
|
1317
1480
|
authorize(input: ActionAuthorizationInput): Promise<boolean>;
|
|
1318
1481
|
/**
|
|
@@ -1320,14 +1483,25 @@ export interface PlatformHostAuthorization {
|
|
|
1320
1483
|
* execution. When absent, the Host reuses `authorize` at this boundary.
|
|
1321
1484
|
*/
|
|
1322
1485
|
authorizeExecution?(input: ActionExecutionAuthorizationInput): Promise<boolean>;
|
|
1486
|
+
/** Optional final execution authority check on the handler transaction, immediately before the effect. */
|
|
1487
|
+
authorizeExecutionInTransaction?(input: ActionExecutionAuthorizationInTransactionInput<TDb>): Promise<boolean>;
|
|
1323
1488
|
/** Optional distinct authorization boundary for human/system approval decisions. */
|
|
1324
1489
|
authorizeApproval?(input: ActionApprovalAuthorizationInput): Promise<boolean>;
|
|
1490
|
+
/** Optional final approval authority check under the locked row in the decision transaction. */
|
|
1491
|
+
authorizeApprovalInTransaction?(input: ActionApprovalAuthorizationInTransactionInput<TDb>): Promise<boolean>;
|
|
1325
1492
|
/**
|
|
1326
1493
|
* Authorization for `requeueOutboxDeadLetter`. There is no action to fall
|
|
1327
1494
|
* back to, so when this is absent every requeue is refused as
|
|
1328
1495
|
* `not_authorized`. A throw propagates and nothing is requeued.
|
|
1329
1496
|
*/
|
|
1330
1497
|
authorizeOutboxRequeue?(input: OutboxRequeueAuthorizationInput): Promise<boolean>;
|
|
1498
|
+
/**
|
|
1499
|
+
* Erasure operator authorization after validation and before store access. No fallback:
|
|
1500
|
+
* absence or a result other than true raises StoredRecordErasureAuthorizationError.
|
|
1501
|
+
* A thrown hook error propagates unchanged; neither outcome reaches the store.
|
|
1502
|
+
* Receives identifying facts and detached validated targets, without redact or stored payloads.
|
|
1503
|
+
*/
|
|
1504
|
+
authorizeStoredRecordErasure?(input: StoredRecordErasureAuthorizationInput): Promise<boolean>;
|
|
1331
1505
|
}
|
|
1332
1506
|
export interface DispatchActionInput {
|
|
1333
1507
|
actionInvocationId: string;
|
|
@@ -1497,7 +1671,7 @@ export interface ErrorTextRedactionContext {
|
|
|
1497
1671
|
}
|
|
1498
1672
|
export interface PlatformHostOptions<TDb> {
|
|
1499
1673
|
store: PlatformHostStore<TDb>;
|
|
1500
|
-
authorization: PlatformHostAuthorization
|
|
1674
|
+
authorization: PlatformHostAuthorization<TDb>;
|
|
1501
1675
|
/** Preferred explicit catalog assembled from this runtime's Fabric modules. */
|
|
1502
1676
|
registry?: Pick<ModuleRegistry<TDb>, "resolveAction" | "resolvePolicy" | "resolveStateMachine"> & Partial<Pick<ModuleRegistry<TDb>, "orderedModules">>;
|
|
1503
1677
|
/** Resolve vertical- or runtime-local actions without mutating the process-wide registry. */
|
|
@@ -1532,9 +1706,29 @@ export interface PlatformHostOptions<TDb> {
|
|
|
1532
1706
|
* approval resume, exhausted attempts, and marker-write failures are not retried.
|
|
1533
1707
|
* Policy persistence, obligation listing/resolution/persistence, state-machine checks,
|
|
1534
1708
|
* the handler transaction, handlers, adapters, and finalization are excluded;
|
|
1535
|
-
* their failure/reconciliation/recovery semantics apply,
|
|
1709
|
+
* their separate failure/reconciliation/recovery semantics apply, including handlerRetry
|
|
1710
|
+
* for confirmed handler rollback, subject to recoveryMaxAttempts.
|
|
1536
1711
|
*/
|
|
1537
1712
|
retryableExecutionMaxAttempts?: number;
|
|
1713
|
+
/** Bounded retries within one execution attempt after confirmed handler rollback. */
|
|
1714
|
+
handlerRetry?: {
|
|
1715
|
+
/** Total transaction tries, including the first; integer 1–10, default 3. One disables retry. */
|
|
1716
|
+
maxAttempts?: number;
|
|
1717
|
+
/** Assert the whole retried unit kept effects in the transaction. Literal true opts in; throws refuse retry. */
|
|
1718
|
+
classify?: (error: unknown, context: {
|
|
1719
|
+
actionId: string;
|
|
1720
|
+
}) => boolean;
|
|
1721
|
+
/** Retry number starts at 1. Default full jitter on 25 ms doubling; clamped to 0–1000 ms. Throws/non-finite stop retry. */
|
|
1722
|
+
delayMs?: number | ((retry: number) => number);
|
|
1723
|
+
/** Called before each delay; attempt is the upcoming try (2..maxAttempts). Sync throws and async rejections are ignored without awaiting. */
|
|
1724
|
+
onRetry?: (info: {
|
|
1725
|
+
actionInvocationId: string;
|
|
1726
|
+
actionId: string;
|
|
1727
|
+
attempt: number;
|
|
1728
|
+
maxAttempts: number;
|
|
1729
|
+
error: unknown;
|
|
1730
|
+
}) => void;
|
|
1731
|
+
};
|
|
1538
1732
|
/**
|
|
1539
1733
|
* Positive integer cap on worker claims for resumed leased running invocations
|
|
1540
1734
|
* including the first (default max(5, retryableExecutionMaxAttempts); Infinity is rejected).
|
|
@@ -1550,6 +1744,8 @@ export interface PlatformHostOptions<TDb> {
|
|
|
1550
1744
|
services?: FabricRuntimeServices;
|
|
1551
1745
|
idempotency?: {
|
|
1552
1746
|
conflictMode?: "audit-only" | "enforce";
|
|
1747
|
+
/** Reserve keyed definitive submission refusals. Requires enforcing identity and store support. */
|
|
1748
|
+
recordRefusals?: boolean;
|
|
1553
1749
|
onConflict?(conflict: IdempotencyConflict): void;
|
|
1554
1750
|
onLegacyRecord?(invocation: ActionInvocationRecord): void;
|
|
1555
1751
|
};
|
|
@@ -1581,6 +1777,8 @@ export interface PlatformHostOptions<TDb> {
|
|
|
1581
1777
|
approvalDefaultTtlMs?: number;
|
|
1582
1778
|
/** Atomic approval lifecycle events and outbox writes; defaults to false. */
|
|
1583
1779
|
approvalLifecycleEvents?: boolean;
|
|
1780
|
+
/** Atomic audit events for refused recording attempts; defaults to false. */
|
|
1781
|
+
approvalDecisionAttemptEvents?: boolean;
|
|
1584
1782
|
/** Durable evaluator/ruleset version recorded with every HITL decision. */
|
|
1585
1783
|
hitlPolicyVersion?: string;
|
|
1586
1784
|
/** Optional portable resolver; provider-specific implementations belong in integration packages. */
|
|
@@ -1696,6 +1894,10 @@ export interface PlatformHostOptions<TDb> {
|
|
|
1696
1894
|
*/
|
|
1697
1895
|
adapterDeadlineMs?: number;
|
|
1698
1896
|
}
|
|
1897
|
+
/** Additive capability; handwritten GovernedActionHost implementations retain their existing shape. */
|
|
1898
|
+
export interface ApprovalDecisionRecordingHost {
|
|
1899
|
+
recordApprovalDecision(id: string, tenantId: string, spaceId: string, request: RecordApprovalDecisionRequest): Promise<RecordApprovalDecisionResult>;
|
|
1900
|
+
}
|
|
1699
1901
|
export interface ApprovalExpiryHost {
|
|
1700
1902
|
expireDueApprovals(input?: ExpireDueApprovalsInput): Promise<{
|
|
1701
1903
|
expired: string[];
|
|
@@ -1748,19 +1950,99 @@ export interface OutboxRequeueHost {
|
|
|
1748
1950
|
requeueOutboxDeadLetter(input: RequeueOutboxDeadLetterInput): Promise<RequeueOutboxDeadLetterResult>;
|
|
1749
1951
|
}
|
|
1750
1952
|
//#endregion
|
|
1953
|
+
//#region src/erasure-types.d.ts
|
|
1954
|
+
type StoredRecordErasureTarget = {
|
|
1955
|
+
readonly kind: "invocation";
|
|
1956
|
+
readonly invocationId: string;
|
|
1957
|
+
} | {
|
|
1958
|
+
readonly kind: "event";
|
|
1959
|
+
readonly eventId: string;
|
|
1960
|
+
};
|
|
1961
|
+
interface ErasurePayloadFields {
|
|
1962
|
+
invocation: "parameters" | "result" | "error" | "provenance" | "authorizationBinding" | "authorizationReconciliation" | "adapterReconciliation" | "hitlReason" | "approvalDecision" | "mutationFootprint" | "executionPrincipal" | "runtimeEvidence" | "pendingCompletion" | "externalCompletion" | "pendingStateTransition" | "finalizationCheckpoint" | "approvalExpiry" | "agentProposal" | "submissionRefusal";
|
|
1963
|
+
adapter: "input" | "output" | "error" | "reconciliation";
|
|
1964
|
+
staged: "parameters" | "lastError";
|
|
1965
|
+
policy_evaluation: "outcome";
|
|
1966
|
+
policy_obligation: "description" | "evidenceReferences" | "metadata";
|
|
1967
|
+
execution_attestation: "attestation";
|
|
1968
|
+
external_reconciliation: "reconciliation";
|
|
1969
|
+
event: "payload" | "provenance";
|
|
1970
|
+
outbox: "lastError" | "traceContext" | "payload" | "provenance";
|
|
1971
|
+
outbox_requeue: "reason" | "priorLastError";
|
|
1972
|
+
}
|
|
1973
|
+
type ErasureRecordKind = keyof ErasurePayloadFields;
|
|
1974
|
+
/** Protected nested keys are omitted from the callback; stores restore structure and overwrite payload digests. */
|
|
1975
|
+
type StoredRecordErasureView = { [K in ErasureRecordKind]: {
|
|
1976
|
+
readonly kind: K;
|
|
1977
|
+
readonly id: string;
|
|
1978
|
+
readonly tenantId: string;
|
|
1979
|
+
readonly spaceId: string;
|
|
1980
|
+
readonly invocationId?: string;
|
|
1981
|
+
readonly eventId?: string;
|
|
1982
|
+
readonly eventType?: string;
|
|
1983
|
+
fields: Partial<Record<ErasurePayloadFields[K], unknown>>;
|
|
1984
|
+
}; }[ErasureRecordKind];
|
|
1985
|
+
/** Validated identifying facts sent to the application authorizer; no stored payload or callback. */
|
|
1986
|
+
interface StoredRecordErasureAuthorizationInput {
|
|
1987
|
+
/** Trusted operator identity supplied by the authenticated application session. */
|
|
1988
|
+
readonly actorId: string;
|
|
1989
|
+
readonly actorType: ActorType;
|
|
1990
|
+
readonly tenantId: string;
|
|
1991
|
+
readonly spaceId: string;
|
|
1992
|
+
readonly requestId: string;
|
|
1993
|
+
readonly targets: readonly StoredRecordErasureTarget[];
|
|
1994
|
+
}
|
|
1995
|
+
interface EraseStoredRecordsInput extends StoredRecordErasureAuthorizationInput {
|
|
1996
|
+
/** Target-lock acquisition budget in milliseconds, 1–60000; default 250. */
|
|
1997
|
+
readonly lockTimeoutMs?: number;
|
|
1998
|
+
/** Rewrite work budget in milliseconds, 1–60000; default 5000. */
|
|
1999
|
+
readonly workTimeoutMs?: number;
|
|
2000
|
+
/** Synchronous JSON-data transformation. A thrown error or invalid result rolls back the batch. */
|
|
2001
|
+
readonly redact: (record: StoredRecordErasureView) => StoredRecordErasureView;
|
|
2002
|
+
}
|
|
2003
|
+
type StoredRecordErasureOutcome = "erased" | "already_erased" | "active" | "not_found";
|
|
2004
|
+
interface EraseStoredRecordsResult {
|
|
2005
|
+
targets: Array<StoredRecordErasureTarget & {
|
|
2006
|
+
outcome: StoredRecordErasureOutcome;
|
|
2007
|
+
}>;
|
|
2008
|
+
/** Records processed, including records processed again by repeat erasure. */
|
|
2009
|
+
counts: Partial<Record<ErasureRecordKind, number>>;
|
|
2010
|
+
}
|
|
2011
|
+
interface ErasablePlatformHostStore<TDb> extends PlatformHostStore<TDb> {
|
|
2012
|
+
/**
|
|
2013
|
+
* Unauthenticated storage port, not an authorization boundary; callers must enforce authorization.
|
|
2014
|
+
* Atomic rewrite/marker/audit operation. The audit retains actorId/actorType as identifying metadata.
|
|
2015
|
+
* Invocation reads expose storedRecordsErased after commit.
|
|
2016
|
+
*/
|
|
2017
|
+
eraseStoredRecords(input: EraseStoredRecordsInput): Promise<EraseStoredRecordsResult>;
|
|
2018
|
+
}
|
|
2019
|
+
interface StoredRecordErasureHost {
|
|
2020
|
+
/** Throws StoredRecordErasureAuthorizationError (not_authorized) before store access on authorization refusal. */
|
|
2021
|
+
eraseStoredRecords(input: EraseStoredRecordsInput): Promise<EraseStoredRecordsResult>;
|
|
2022
|
+
}
|
|
2023
|
+
export declare const HOST_RECORDS_ERASED_EVENT: "HostRecordsErased";
|
|
2024
|
+
/** Sentinel replacing required payload digests after stored-record erasure. */
|
|
2025
|
+
export declare const ERASED_DIGEST: "erased";
|
|
2026
|
+
//#endregion
|
|
1751
2027
|
//#region src/host.d.ts
|
|
1752
|
-
export declare function createGovernedActionHost<TDb>(options: PlatformHostOptions<TDb>): GovernedActionHost & OutboxRequeueHost & ApprovalExpiryHost;
|
|
2028
|
+
export declare function createGovernedActionHost<TDb>(options: PlatformHostOptions<TDb>): GovernedActionHost & OutboxRequeueHost & ApprovalExpiryHost & ApprovalDecisionRecordingHost & StoredRecordErasureHost;
|
|
1753
2029
|
//#endregion
|
|
1754
2030
|
//#region src/memory-store.d.ts
|
|
2031
|
+
/**
|
|
2032
|
+
* Optional domain snapshot/restore binder. The Host handler callback can request
|
|
2033
|
+
* rollback confirmation after a failed callback and successful undo/restore.
|
|
2034
|
+
* Commit failures and providerless internal transactions supply no confirmation.
|
|
2035
|
+
* Ordinary public transaction callbacks retain their original error objects.
|
|
2036
|
+
*/
|
|
1755
2037
|
export interface MemoryPlatformHostTransactionProvider<TDb> {
|
|
1756
2038
|
snapshot(db: TDb): TDb;
|
|
1757
2039
|
restore(db: TDb, snapshot: TDb): void;
|
|
1758
2040
|
}
|
|
1759
|
-
export declare class MemoryPlatformHostStore<TDb> implements RecoverablePlatformHostStore<TDb>, ApprovalPlatformHostStore<TDb>, GovernancePlatformHostStore<TDb>, OutboxPlatformHostStore<TDb>, OutboxRequeuePlatformHostStore<TDb>, StagedInvocationPlatformHostStore<TDb> {
|
|
2041
|
+
export declare class MemoryPlatformHostStore<TDb> implements ErasablePlatformHostStore<TDb>, RecoverablePlatformHostStore<TDb>, ApprovalPlatformHostStore<TDb>, GovernancePlatformHostStore<TDb>, OutboxPlatformHostStore<TDb>, OutboxRequeuePlatformHostStore<TDb>, StagedInvocationPlatformHostStore<TDb> {
|
|
1760
2042
|
readonly db: TDb;
|
|
1761
2043
|
readonly transactionalOutbox: boolean;
|
|
1762
2044
|
readonly transactionalApprovalLifecycle: boolean;
|
|
1763
|
-
|
|
2045
|
+
readonly transactionalApprovalAuthorization = true;
|
|
1764
2046
|
readonly transactionalStagedInvocations: boolean;
|
|
1765
2047
|
transactionWithEvents?: <TResult>(run: (transaction: PlatformHostMutationTransaction<TDb>) => Promise<TResult>) => Promise<TResult>;
|
|
1766
2048
|
private adapterCommit;
|
|
@@ -1781,10 +2063,16 @@ export declare class MemoryPlatformHostStore<TDb> implements RecoverablePlatform
|
|
|
1781
2063
|
* `private`, as for the store's other internals, is a compile-time guard.
|
|
1782
2064
|
*/
|
|
1783
2065
|
private readonly outboxRequeues;
|
|
2066
|
+
private readonly erasedStages;
|
|
2067
|
+
private readonly erasureMarkers;
|
|
2068
|
+
private isErased;
|
|
2069
|
+
private assertNotErased;
|
|
2070
|
+
eraseStoredRecords(request: EraseStoredRecordsInput): Promise<EraseStoredRecordsResult>;
|
|
1784
2071
|
constructor(db: TDb, transactionProvider?: MemoryPlatformHostTransactionProvider<TDb>);
|
|
1785
2072
|
transaction<TResult>(run: (db: TDb) => Promise<TResult>): Promise<TResult>;
|
|
1786
2073
|
private runTransactionWithEvents;
|
|
1787
2074
|
createActionInvocation(input: CreateActionInvocationInput): Promise<ActionInvocationRecord>;
|
|
2075
|
+
recordSubmissionRefusal(input: RecordSubmissionRefusalInput): Promise<ActionInvocationRecord>;
|
|
1788
2076
|
createActionInvocationForStagedLease(input: CreateStagedActionInvocationInput): Promise<CreateStagedActionInvocationResult>;
|
|
1789
2077
|
private applyStagedBatch;
|
|
1790
2078
|
getActionInvocation(id: string, tenantId: string, spaceId: string): Promise<ActionInvocationRecord | undefined>;
|
|
@@ -1793,7 +2081,8 @@ export declare class MemoryPlatformHostStore<TDb> implements RecoverablePlatform
|
|
|
1793
2081
|
recordHitlDecision(actionInvocationId: string, tenantId: string, spaceId: string, decision: HitlDecisionEvidence): Promise<ActionInvocationRecord>;
|
|
1794
2082
|
private runApprovalTransaction;
|
|
1795
2083
|
parkApproval(input: ParkApprovalInput): Promise<ApprovalDecisionTransitionResult>;
|
|
1796
|
-
|
|
2084
|
+
recordApprovalDecision(input: RecordApprovalDecisionStoreInput<TDb>): Promise<RecordApprovalDecisionStoreResult>;
|
|
2085
|
+
beginApprovalDecision(input: BeginApprovalDecisionInput<TDb>): Promise<ApprovalDecisionTransitionResult>;
|
|
1797
2086
|
expireDueApprovals(input: ExpireDueApprovalsStoreInput): Promise<ActionInvocationRecord[]>;
|
|
1798
2087
|
appendPolicyEvaluation(record: PolicyEvaluationRecord): Promise<void>;
|
|
1799
2088
|
recordMutationGovernance(actionInvocationId: string, tenantId: string, spaceId: string, context: Pick<ActionInvocationRecord, "mutationFootprint" | "executionPrincipal"> & {
|
|
@@ -1824,13 +2113,14 @@ export declare class MemoryPlatformHostStore<TDb> implements RecoverablePlatform
|
|
|
1824
2113
|
availableAt: Date;
|
|
1825
2114
|
deadLetter: boolean;
|
|
1826
2115
|
}): Promise<void>;
|
|
1827
|
-
renewOutboxLease(input:
|
|
2116
|
+
renewOutboxLease(input: Parameters<OutboxPlatformHostStore<TDb>["renewOutboxLease"]>[0]): Promise<boolean>;
|
|
2117
|
+
renewOutboxLeaseAndRead(input: {
|
|
1828
2118
|
id: string;
|
|
1829
2119
|
workerId: string;
|
|
1830
2120
|
leaseToken: number;
|
|
1831
2121
|
leaseDurationMs: number;
|
|
1832
2122
|
now?: Date;
|
|
1833
|
-
}): Promise<
|
|
2123
|
+
}): Promise<OutboxRecord | undefined>;
|
|
1834
2124
|
listOutbox(input?: {
|
|
1835
2125
|
tenantId?: string;
|
|
1836
2126
|
spaceId?: string;
|
|
@@ -1972,21 +2262,37 @@ export interface PostgresPlatformHostTransactionContext<TDb> {
|
|
|
1972
2262
|
* `pg.PoolClient`. Production applications provide this adapter so domain
|
|
1973
2263
|
* methods and Host ledger writes share one PostgreSQL transaction.
|
|
1974
2264
|
*/
|
|
2265
|
+
/**
|
|
2266
|
+
* May reject with ConfirmedTransactionRollback(callbackError) after successful rollback
|
|
2267
|
+
* of a failed callback. Providers omitting that evidence get no in-attempt handler retry.
|
|
2268
|
+
* Commit errors must not be represented as confirmed callback rollback. The store exposes
|
|
2269
|
+
* evidence at the Host handler callback request and normalizes it for other consumers.
|
|
2270
|
+
*/
|
|
1975
2271
|
export interface PostgresPlatformHostTransactionProvider<TDb> {
|
|
1976
2272
|
run<TResult>(run: (context: PostgresPlatformHostTransactionContext<TDb>) => Promise<TResult>): Promise<TResult>;
|
|
1977
2273
|
}
|
|
1978
2274
|
/** Durable mutation-pipeline ledger for Databricks Lakebase or standard Postgres. */
|
|
1979
|
-
export declare class PostgresPlatformHostStore<TDb> implements RecoverablePlatformHostStore<TDb>, ApprovalPlatformHostStore<TDb>, GovernancePlatformHostStore<TDb>, OutboxPlatformHostStore<TDb>, OutboxRequeuePlatformHostStore<TDb>, StagedInvocationPlatformHostStore<TDb> {
|
|
2275
|
+
export declare class PostgresPlatformHostStore<TDb> implements ErasablePlatformHostStore<TDb>, RecoverablePlatformHostStore<TDb>, ApprovalPlatformHostStore<TDb>, GovernancePlatformHostStore<TDb>, OutboxPlatformHostStore<TDb>, OutboxRequeuePlatformHostStore<TDb>, StagedInvocationPlatformHostStore<TDb> {
|
|
1980
2276
|
readonly db: TDb;
|
|
1981
2277
|
private readonly sql;
|
|
2278
|
+
private readonly transactionProvider?;
|
|
1982
2279
|
readonly transactionWithEvents?: AtomicMutationPlatformHostStore<TDb>["transactionWithEvents"];
|
|
2280
|
+
private ownerLocksPersist;
|
|
2281
|
+
private readonly lockedOwners;
|
|
1983
2282
|
readonly transactionalOutbox: boolean;
|
|
1984
2283
|
readonly transactionalApprovalLifecycle: boolean;
|
|
2284
|
+
readonly transactionalApprovalAuthorization: boolean;
|
|
1985
2285
|
readonly transactionalStagedInvocations: boolean;
|
|
1986
|
-
constructor(db: TDb, sql: PlatformHostSqlClient, transactionProvider?: PostgresPlatformHostTransactionProvider<TDb>);
|
|
2286
|
+
constructor(db: TDb, sql: PlatformHostSqlClient, transactionProvider?: PostgresPlatformHostTransactionProvider<TDb> | undefined);
|
|
2287
|
+
/** Internal provider entry: non-handler consumers retain their original error objects. */
|
|
2288
|
+
private runTransaction;
|
|
2289
|
+
private refuseErased;
|
|
2290
|
+
private ownerFence;
|
|
1987
2291
|
ensureSchema(): Promise<void>;
|
|
2292
|
+
eraseStoredRecords(request: EraseStoredRecordsInput): Promise<EraseStoredRecordsResult>;
|
|
1988
2293
|
transaction<TResult>(run: (db: TDb) => Promise<TResult>): Promise<TResult>;
|
|
1989
2294
|
createActionInvocation(input: CreateActionInvocationInput): Promise<ActionInvocationRecord>;
|
|
2295
|
+
recordSubmissionRefusal(input: RecordSubmissionRefusalInput): Promise<ActionInvocationRecord>;
|
|
1990
2296
|
createActionInvocationForStagedLease(input: CreateStagedActionInvocationInput): Promise<CreateStagedActionInvocationResult>;
|
|
1991
2297
|
stageInvocations(records: readonly StagedInvocationRecord[]): Promise<void>;
|
|
1992
2298
|
getActionInvocation(id: string, tenantId: string, spaceId: string): Promise<ActionInvocationRecord | undefined>;
|
|
@@ -1995,7 +2301,9 @@ export declare class PostgresPlatformHostStore<TDb> implements RecoverablePlatfo
|
|
|
1995
2301
|
recordHitlDecision(actionInvocationId: string, tenantId: string, spaceId: string, decision: HitlDecisionEvidence): Promise<ActionInvocationRecord>;
|
|
1996
2302
|
parkApproval(input: ParkApprovalInput): Promise<ApprovalDecisionTransitionResult>;
|
|
1997
2303
|
expireDueApprovals(input: ExpireDueApprovalsStoreInput): Promise<ActionInvocationRecord[]>;
|
|
1998
|
-
|
|
2304
|
+
private lockDueApprovals;
|
|
2305
|
+
recordApprovalDecision(input: RecordApprovalDecisionStoreInput<TDb>): Promise<RecordApprovalDecisionStoreResult>;
|
|
2306
|
+
beginApprovalDecision(input: BeginApprovalDecisionInput<TDb>): Promise<ApprovalDecisionTransitionResult>;
|
|
1999
2307
|
appendPolicyEvaluation(record: PolicyEvaluationRecord): Promise<void>;
|
|
2000
2308
|
recordMutationGovernance(actionInvocationId: string, tenantId: string, spaceId: string, context: {
|
|
2001
2309
|
footprint: NonNullable<ActionInvocationRecord["mutationFootprint"]>;
|
|
@@ -2024,13 +2332,14 @@ export declare class PostgresPlatformHostStore<TDb> implements RecoverablePlatfo
|
|
|
2024
2332
|
availableAt: Date;
|
|
2025
2333
|
deadLetter: boolean;
|
|
2026
2334
|
}): Promise<void>;
|
|
2027
|
-
renewOutboxLease(input:
|
|
2335
|
+
renewOutboxLease(input: Parameters<OutboxPlatformHostStore<TDb>["renewOutboxLease"]>[0]): Promise<boolean>;
|
|
2336
|
+
renewOutboxLeaseAndRead(input: {
|
|
2028
2337
|
id: string;
|
|
2029
2338
|
workerId: string;
|
|
2030
2339
|
leaseToken: number;
|
|
2031
2340
|
leaseDurationMs: number;
|
|
2032
2341
|
now?: Date;
|
|
2033
|
-
}): Promise<
|
|
2342
|
+
}): Promise<OutboxRecord | undefined>;
|
|
2034
2343
|
listOutbox(input?: {
|
|
2035
2344
|
tenantId?: string;
|
|
2036
2345
|
spaceId?: string;
|
|
@@ -2115,7 +2424,9 @@ export declare class PostgresPlatformHostStore<TDb> implements RecoverablePlatfo
|
|
|
2115
2424
|
updateLeasedActionInvocation(input: UpdateLeasedActionInvocationInput): Promise<boolean>;
|
|
2116
2425
|
renewActionInvocationLease(input: RenewActionInvocationLeaseInput): Promise<boolean>;
|
|
2117
2426
|
listEvents(tenantId: string, spaceId: string): Promise<AssetEventEnvelope[]>;
|
|
2118
|
-
getEvent(id: string, tenantId: string, spaceId: string): Promise<AssetEventEnvelope
|
|
2427
|
+
getEvent(id: string, tenantId: string, spaceId: string): Promise<(AssetEventEnvelope & {
|
|
2428
|
+
readonly storedRecordsErased?: true;
|
|
2429
|
+
}) | undefined>;
|
|
2119
2430
|
}
|
|
2120
2431
|
//#endregion
|
|
2121
2432
|
//#region src/postgres-migrations.d.ts
|
|
@@ -2259,6 +2570,11 @@ export declare function prepareStagedInvocationBatch<TDb>(input: PrepareStagedIn
|
|
|
2259
2570
|
export declare function stagedInvocationRequestIdentity(record: StagedInvocationRecord): string;
|
|
2260
2571
|
export declare function cloneStagedInvocationRecord(record: StagedInvocationRecord): StagedInvocationRecord;
|
|
2261
2572
|
export declare function asStagedInvocationStore<TDb>(store: PlatformHostStore<TDb>): StagedInvocationPlatformHostStore<TDb> | undefined;
|
|
2573
|
+
/** Placeholder for published payload-covering batch digests replaced by migration 16. */
|
|
2574
|
+
export declare const LEGACY_BATCH_DIGEST = "legacy-batch";
|
|
2575
|
+
/** Replay comparison used by both built-in stores. Compares the full request identity,
|
|
2576
|
+
* skipping only the batch-digest comparison when the stored row carries LEGACY_BATCH_DIGEST. */
|
|
2577
|
+
export declare function stagedInvocationRequestMatches(stored: StagedInvocationRecord, incoming: StagedInvocationRecord): boolean;
|
|
2262
2578
|
//#endregion
|
|
2263
2579
|
//#region src/tenant-isolation.d.ts
|
|
2264
2580
|
export interface TenantIsolationScope {
|
|
@@ -2291,13 +2607,13 @@ export interface TenantIsolationSubject<TDb = unknown> {
|
|
|
2291
2607
|
}>;
|
|
2292
2608
|
/**
|
|
2293
2609
|
* Optional: put the host and store back to a known state before a check.
|
|
2294
|
-
* The checks tolerate accumulated state, and
|
|
2295
|
-
*
|
|
2610
|
+
* The checks tolerate accumulated state, and direct probes use terminal rows
|
|
2611
|
+
* or retire the active rows they create, so this exists for subjects whose store is shared.
|
|
2296
2612
|
*/
|
|
2297
2613
|
reset?(): Promise<void> | void;
|
|
2298
2614
|
}
|
|
2299
2615
|
export interface TenantIsolationCheck {
|
|
2300
|
-
id: "fabric.tenancy.invocation-scoped-read.v1" | "fabric.tenancy.idempotency-key-scoped.v1" | "fabric.tenancy.events-scoped.v1" | "fabric.tenancy.worker-claim-scoped.v1" | "fabric.tenancy.staged-invocation-scoped.v1" | "fabric.tenancy.completion-scoped.v1" | "fabric.tenancy.projection-scoped.v1" | "fabric.tenancy.adapter-invocation-read-scoped.v1" | "fabric.tenancy.adapter-invocation-write-scoped.v1";
|
|
2616
|
+
id: "fabric.tenancy.invocation-scoped-read.v1" | "fabric.tenancy.idempotency-key-scoped.v1" | "fabric.tenancy.submission-refusal-scoped.v1" | "fabric.tenancy.events-scoped.v1" | "fabric.tenancy.worker-claim-scoped.v1" | "fabric.tenancy.staged-invocation-scoped.v1" | "fabric.tenancy.completion-scoped.v1" | "fabric.tenancy.projection-scoped.v1" | "fabric.tenancy.adapter-invocation-read-scoped.v1" | "fabric.tenancy.adapter-invocation-write-scoped.v1";
|
|
2301
2617
|
run(subject: TenantIsolationSubject): Promise<string[]>;
|
|
2302
2618
|
}
|
|
2303
2619
|
export interface TenantIsolationResult {
|
|
@@ -2312,9 +2628,10 @@ export interface TenantIsolationResult {
|
|
|
2312
2628
|
/**
|
|
2313
2629
|
* The suite a deployment of the host must pass before it claims isolation.
|
|
2314
2630
|
*
|
|
2315
|
-
*
|
|
2631
|
+
* Ten checks: an invocation cannot be read, executed, or completed under
|
|
2316
2632
|
* another tenant's scope; an idempotency key is a tenant's own, so the same
|
|
2317
|
-
* key in two tenants is two invocations;
|
|
2633
|
+
* key in two tenants is two invocations; optional recorded refusals retain
|
|
2634
|
+
* tenant and space scope, including when ordinary creation encounters a refusal; a tenant's event stream carries no
|
|
2318
2635
|
* other tenant's events; a worker scoped to one tenant does not claim another's
|
|
2319
2636
|
* work; staged listing and claiming retain tenant and space scope; an adapter
|
|
2320
2637
|
* checkpoint cannot be read or written under another tenant, space, or owning
|
|
@@ -2401,4 +2718,211 @@ export declare function eventAppendChecks(): readonly EventAppendCheck[];
|
|
|
2401
2718
|
*/
|
|
2402
2719
|
export declare function runEventAppendChecks<TDb>(subject: EventAppendSubject<TDb>): Promise<EventAppendResult>;
|
|
2403
2720
|
//#endregion
|
|
2404
|
-
|
|
2721
|
+
//#region src/erasure.d.ts
|
|
2722
|
+
export declare function createStoredRecordErasureHost<TDb>(store: PlatformHostStore<TDb>, authorization: Pick<PlatformHostAuthorization<TDb>, "authorizeStoredRecordErasure">): StoredRecordErasureHost;
|
|
2723
|
+
//#endregion
|
|
2724
|
+
//#region src/erasure-conformance.d.ts
|
|
2725
|
+
export interface ErasureProbeScope {
|
|
2726
|
+
tenantId: string;
|
|
2727
|
+
spaceId: string;
|
|
2728
|
+
invocationId: string;
|
|
2729
|
+
}
|
|
2730
|
+
export interface ErasureSubject<TDb = unknown> {
|
|
2731
|
+
store: PlatformHostStore<TDb> & Partial<ErasablePlatformHostStore<TDb>> & {
|
|
2732
|
+
listEvents?(tenantId: string, spaceId: string): Promise<AssetEventEnvelope[]>;
|
|
2733
|
+
};
|
|
2734
|
+
tenantId: string;
|
|
2735
|
+
/** Test-store fixture access for record kinds not readable through the base store port. */
|
|
2736
|
+
payloadRecords?: {
|
|
2737
|
+
seed(scope: ErasureProbeScope, sentinel: string): Promise<void>;
|
|
2738
|
+
read(scope: ErasureProbeScope): Promise<readonly {
|
|
2739
|
+
kind: ErasureRecordKind;
|
|
2740
|
+
value: unknown;
|
|
2741
|
+
}[]>;
|
|
2742
|
+
};
|
|
2743
|
+
}
|
|
2744
|
+
export interface ErasureCheck {
|
|
2745
|
+
id: string;
|
|
2746
|
+
run(subject: ErasureSubject): Promise<string[]>;
|
|
2747
|
+
}
|
|
2748
|
+
export interface ErasureResult {
|
|
2749
|
+
passed: boolean;
|
|
2750
|
+
checks: Array<{
|
|
2751
|
+
id: string;
|
|
2752
|
+
status: "passed" | "failed" | "skipped";
|
|
2753
|
+
evidence: string[];
|
|
2754
|
+
error?: string;
|
|
2755
|
+
}>;
|
|
2756
|
+
}
|
|
2757
|
+
/** Destructive probes for isolated test stores; leave evidence in fresh probe spaces. */
|
|
2758
|
+
export declare function erasureChecks(): readonly ErasureCheck[];
|
|
2759
|
+
export declare function runErasureChecks<TDb>(subject: ErasureSubject<TDb>): Promise<ErasureResult>;
|
|
2760
|
+
//#endregion
|
|
2761
|
+
//#region src/erasure-errors.d.ts
|
|
2762
|
+
/** Host authorization refusal; contains no target existence or authorizer failure details. */
|
|
2763
|
+
export declare class StoredRecordErasureAuthorizationError extends Error {
|
|
2764
|
+
readonly refusal = "not_authorized";
|
|
2765
|
+
constructor(message: string);
|
|
2766
|
+
}
|
|
2767
|
+
/** A later mutation of an erased record was refused. */
|
|
2768
|
+
export declare class StoredRecordsErasedError extends Error {
|
|
2769
|
+
readonly code = "HOST_RECORDS_ERASED";
|
|
2770
|
+
constructor();
|
|
2771
|
+
}
|
|
2772
|
+
/** Erasure could not lock its targets or finish within the configured budget. */
|
|
2773
|
+
export declare class ErasureBusyError extends Error {
|
|
2774
|
+
readonly reason: "lock_timeout" | "work_timeout";
|
|
2775
|
+
readonly code = "HOST_ERASURE_BUSY";
|
|
2776
|
+
constructor(reason: "lock_timeout" | "work_timeout", options?: ErrorOptions);
|
|
2777
|
+
}
|
|
2778
|
+
//#endregion
|
|
2779
|
+
//#region src/staged-invocation-conformance.d.ts
|
|
2780
|
+
export type StagedContractStore = StagedInvocationPlatformHostStore<unknown> & AtomicMutationPlatformHostStore<unknown>;
|
|
2781
|
+
export interface StagedCreateRotateRaceInput {
|
|
2782
|
+
record: StagedInvocationRecord;
|
|
2783
|
+
workerId: string;
|
|
2784
|
+
leaseToken: number;
|
|
2785
|
+
now: Date;
|
|
2786
|
+
invocation: CreateActionInvocationInput & {
|
|
2787
|
+
stagedOrigin: {
|
|
2788
|
+
parentInvocationId: string;
|
|
2789
|
+
stageKey: string;
|
|
2790
|
+
principal?: string;
|
|
2791
|
+
};
|
|
2792
|
+
};
|
|
2793
|
+
}
|
|
2794
|
+
export interface StagedCreateRotateRaceOutcome {
|
|
2795
|
+
creation: CreateStagedActionInvocationResult;
|
|
2796
|
+
rotatedToken: number | undefined;
|
|
2797
|
+
}
|
|
2798
|
+
/**
|
|
2799
|
+
* A store whose fence can interleave with rotation (PostgreSQL) supplies the
|
|
2800
|
+
* two races with the first operation held open in a transaction, proving the
|
|
2801
|
+
* second waits for it. Without them the contract runs both operations
|
|
2802
|
+
* concurrently, which serializes in the memory store.
|
|
2803
|
+
*/
|
|
2804
|
+
export interface StagedContractHarness {
|
|
2805
|
+
store: StagedContractStore;
|
|
2806
|
+
/** Fenced create held uncommitted; a rotation under the same token must wait for it. */
|
|
2807
|
+
raceCreateThenRotate?(input: StagedCreateRotateRaceInput): Promise<StagedCreateRotateRaceOutcome>;
|
|
2808
|
+
/** Rotation held uncommitted; a fenced create under the old token must wait, then create nothing. */
|
|
2809
|
+
raceRotateThenCreate?(input: StagedCreateRotateRaceInput): Promise<StagedCreateRotateRaceOutcome>;
|
|
2810
|
+
}
|
|
2811
|
+
export interface StagedInvocationSubject {
|
|
2812
|
+
makeHarness(): Promise<StagedContractHarness>;
|
|
2813
|
+
}
|
|
2814
|
+
export interface StagedInvocationCheck {
|
|
2815
|
+
id: string;
|
|
2816
|
+
run(subject: StagedInvocationSubject): Promise<string[]>;
|
|
2817
|
+
}
|
|
2818
|
+
export interface StagedInvocationResult {
|
|
2819
|
+
passed: boolean;
|
|
2820
|
+
checks: Array<{
|
|
2821
|
+
id: string;
|
|
2822
|
+
status: "passed" | "failed" | "skipped";
|
|
2823
|
+
evidence: string[];
|
|
2824
|
+
error?: string;
|
|
2825
|
+
}>;
|
|
2826
|
+
}
|
|
2827
|
+
/** Destructive probes for isolated test stores; leave records in fresh probe spaces. */
|
|
2828
|
+
export declare function stagedInvocationChecks(): readonly StagedInvocationCheck[];
|
|
2829
|
+
export declare function runStagedInvocationChecks(subject: StagedInvocationSubject): Promise<StagedInvocationResult>;
|
|
2830
|
+
//#endregion
|
|
2831
|
+
//#region src/outbox-requeue-conformance.d.ts
|
|
2832
|
+
export interface OutboxRequeueSubject {
|
|
2833
|
+
makeStore(): Promise<OutboxRequeuePlatformHostStore<unknown>>;
|
|
2834
|
+
}
|
|
2835
|
+
export interface OutboxRequeueCheck {
|
|
2836
|
+
id: string;
|
|
2837
|
+
run(subject: OutboxRequeueSubject): Promise<string[]>;
|
|
2838
|
+
}
|
|
2839
|
+
export interface OutboxRequeueResult {
|
|
2840
|
+
passed: boolean;
|
|
2841
|
+
checks: Array<{
|
|
2842
|
+
id: string;
|
|
2843
|
+
status: "passed" | "failed" | "skipped";
|
|
2844
|
+
evidence: string[];
|
|
2845
|
+
error?: string;
|
|
2846
|
+
}>;
|
|
2847
|
+
}
|
|
2848
|
+
/** Destructive probes for isolated test stores; leave outbox and audit records under fresh identities. */
|
|
2849
|
+
export declare function outboxRequeueChecks(): readonly OutboxRequeueCheck[];
|
|
2850
|
+
export declare function runOutboxRequeueChecks(subject: OutboxRequeueSubject): Promise<OutboxRequeueResult>;
|
|
2851
|
+
//#endregion
|
|
2852
|
+
//#region src/approval-conformance.d.ts
|
|
2853
|
+
export type ApprovalCheckStore = ApprovalPlatformHostStore<{}> & Partial<AtomicMutationPlatformHostStore<{}>> & RecoverablePlatformHostStore<{}> & OutboxPlatformHostStore<{}>;
|
|
2854
|
+
export interface ApprovalSubject {
|
|
2855
|
+
makeStore(): Promise<ApprovalCheckStore>;
|
|
2856
|
+
}
|
|
2857
|
+
export interface ApprovalCheck {
|
|
2858
|
+
id: string;
|
|
2859
|
+
run(subject: ApprovalSubject): Promise<string[]>;
|
|
2860
|
+
}
|
|
2861
|
+
export interface ApprovalResult {
|
|
2862
|
+
passed: boolean;
|
|
2863
|
+
checks: Array<{
|
|
2864
|
+
id: string;
|
|
2865
|
+
status: "passed" | "failed" | "skipped";
|
|
2866
|
+
evidence: string[];
|
|
2867
|
+
error?: string;
|
|
2868
|
+
}>;
|
|
2869
|
+
}
|
|
2870
|
+
/** Destructive probes for isolated test stores; leave invocation, event and outbox evidence under fresh identities. */
|
|
2871
|
+
export declare function approvalChecks(): readonly ApprovalCheck[];
|
|
2872
|
+
export declare function runApprovalChecks(subject: ApprovalSubject): Promise<ApprovalResult>;
|
|
2873
|
+
//#endregion
|
|
2874
|
+
//#region src/outbox-relay-conformance.d.ts
|
|
2875
|
+
export interface OutboxRelaySubject {
|
|
2876
|
+
makeStore(): Promise<OutboxPlatformHostStore<unknown>>;
|
|
2877
|
+
}
|
|
2878
|
+
export interface OutboxRelayCheck {
|
|
2879
|
+
id: string;
|
|
2880
|
+
run(subject: OutboxRelaySubject): Promise<string[]>;
|
|
2881
|
+
}
|
|
2882
|
+
export interface OutboxRelayConformanceResult {
|
|
2883
|
+
passed: boolean;
|
|
2884
|
+
checks: Array<{
|
|
2885
|
+
id: string;
|
|
2886
|
+
status: "passed" | "failed" | "skipped";
|
|
2887
|
+
evidence: string[];
|
|
2888
|
+
error?: string;
|
|
2889
|
+
}>;
|
|
2890
|
+
}
|
|
2891
|
+
/** Destructive probes for isolated test stores; leave outbox records under fresh identities and spaces. */
|
|
2892
|
+
export declare function outboxRelayChecks(): readonly OutboxRelayCheck[];
|
|
2893
|
+
export declare function runOutboxRelayChecks(subject: OutboxRelaySubject): Promise<OutboxRelayConformanceResult>;
|
|
2894
|
+
//#endregion
|
|
2895
|
+
//#region src/invocation-idempotency-conformance.d.ts
|
|
2896
|
+
export interface InvocationIdempotencySubject {
|
|
2897
|
+
makeStore(): Promise<PlatformHostStore<unknown>>;
|
|
2898
|
+
}
|
|
2899
|
+
export interface InvocationIdempotencyCheck {
|
|
2900
|
+
id: string;
|
|
2901
|
+
run(subject: InvocationIdempotencySubject): Promise<string[]>;
|
|
2902
|
+
}
|
|
2903
|
+
export interface InvocationIdempotencyResult {
|
|
2904
|
+
passed: boolean;
|
|
2905
|
+
checks: Array<{
|
|
2906
|
+
id: string;
|
|
2907
|
+
status: "passed" | "failed" | "skipped";
|
|
2908
|
+
evidence: string[];
|
|
2909
|
+
error?: string;
|
|
2910
|
+
}>;
|
|
2911
|
+
}
|
|
2912
|
+
/** Destructive probes for isolated test stores; leave invocation records under fresh identities and spaces. */
|
|
2913
|
+
export declare function invocationIdempotencyChecks(): readonly InvocationIdempotencyCheck[];
|
|
2914
|
+
export declare function runInvocationIdempotencyChecks(subject: InvocationIdempotencySubject): Promise<InvocationIdempotencyResult>;
|
|
2915
|
+
//#endregion
|
|
2916
|
+
//#region src/transaction-rollback.d.ts
|
|
2917
|
+
/** Evidence from a transaction provider that rollback completed successfully. */
|
|
2918
|
+
export declare class ConfirmedTransactionRollback extends Error {
|
|
2919
|
+
readonly name = "ConfirmedTransactionRollback";
|
|
2920
|
+
readonly code: "TRANSACTION_ROLLBACK_CONFIRMED";
|
|
2921
|
+
constructor(cause: unknown);
|
|
2922
|
+
}
|
|
2923
|
+
/** Recognise rollback evidence across ESM/CommonJS or other package copies. */
|
|
2924
|
+
export declare function isConfirmedTransactionRollback(error: unknown): error is ConfirmedTransactionRollback;
|
|
2925
|
+
/** Inspect up to 16 errors, failing closed on cycles or unreadable properties. Intended for handlerRetry.classify. */
|
|
2926
|
+
export declare function isTransientPostgresTransactionError(error: unknown): boolean;
|
|
2927
|
+
//#endregion
|
|
2928
|
+
export { type ErasablePlatformHostStore, type EraseStoredRecordsInput, type EraseStoredRecordsResult, type ErasurePayloadFields, type ErasureRecordKind, type StoredRecordErasureAuthorizationInput, type StoredRecordErasureHost, type StoredRecordErasureOutcome, type StoredRecordErasureTarget, type StoredRecordErasureView, canonicalJson };
|