@fabricorg/platform-host 8.8.0 → 8.10.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 +333 -0
- package/README.md +782 -10
- package/dist/index.cjs +6533 -419
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +608 -36
- package/dist/index.d.ts +608 -36
- package/dist/index.js +6512 -424
- package/dist/index.js.map +1 -1
- package/package.json +5 -5
package/dist/index.d.cts
CHANGED
|
@@ -1,5 +1,79 @@
|
|
|
1
1
|
import { ActionDefinition, ActionId, ActionStatus, ActorType, AdapterCircuitBreakerProvider, AdapterImplementation, AgentActionPolicyContext, AgentActionPolicyDecision, AgentActionRiskTier, AgentActionRoute, AssetEventEnvelope, EvidencePacketReference, ExecutionAttestation, ExecutionPrincipal, ExternalReconciliation, FabricRuntimeServices, GovernanceRuntimeEvidence, ModuleRegistry, MutationFootprint, MutationGovernanceResolver, PolicyObligation, PolicyObligationStatus, PolicyOutcome, RuntimePolicyDefinition, StagedInvocationRequest, canonicalJson } from "@fabricorg/platform";
|
|
2
2
|
import { AssemblyLockfile } from "@fabricorg/assembly";
|
|
3
|
+
//#region src/erasure-types.d.ts
|
|
4
|
+
type StoredRecordErasureTarget = {
|
|
5
|
+
readonly kind: "invocation";
|
|
6
|
+
readonly invocationId: string;
|
|
7
|
+
} | {
|
|
8
|
+
readonly kind: "event";
|
|
9
|
+
readonly eventId: string;
|
|
10
|
+
};
|
|
11
|
+
interface ErasurePayloadFields {
|
|
12
|
+
invocation: "parameters" | "result" | "error" | "provenance" | "authorizationBinding" | "authorizationReconciliation" | "adapterReconciliation" | "hitlReason" | "approvalDecision" | "mutationFootprint" | "executionPrincipal" | "runtimeEvidence" | "pendingCompletion" | "externalCompletion" | "pendingStateTransition" | "finalizationCheckpoint" | "approvalExpiry" | "agentProposal" | "submissionRefusal";
|
|
13
|
+
adapter: "input" | "output" | "error" | "reconciliation";
|
|
14
|
+
staged: "parameters" | "lastError";
|
|
15
|
+
policy_evaluation: "outcome";
|
|
16
|
+
policy_obligation: "description" | "evidenceReferences" | "metadata";
|
|
17
|
+
execution_attestation: "attestation";
|
|
18
|
+
external_reconciliation: "reconciliation";
|
|
19
|
+
event: "payload" | "provenance";
|
|
20
|
+
outbox: "lastError" | "traceContext" | "payload" | "provenance";
|
|
21
|
+
outbox_requeue: "reason" | "priorLastError";
|
|
22
|
+
}
|
|
23
|
+
type ErasureRecordKind = keyof ErasurePayloadFields;
|
|
24
|
+
/** Protected nested keys are omitted from the callback; stores restore structure and overwrite payload digests. */
|
|
25
|
+
type StoredRecordErasureView = { [K in ErasureRecordKind]: {
|
|
26
|
+
readonly kind: K;
|
|
27
|
+
readonly id: string;
|
|
28
|
+
readonly tenantId: string;
|
|
29
|
+
readonly spaceId: string;
|
|
30
|
+
readonly invocationId?: string;
|
|
31
|
+
readonly eventId?: string;
|
|
32
|
+
readonly eventType?: string;
|
|
33
|
+
fields: Partial<Record<ErasurePayloadFields[K], unknown>>;
|
|
34
|
+
}; }[ErasureRecordKind];
|
|
35
|
+
/** Validated identifying facts sent to the application authorizer; no stored payload or callback. */
|
|
36
|
+
interface StoredRecordErasureAuthorizationInput {
|
|
37
|
+
/** Trusted operator identity supplied by the authenticated application session. */
|
|
38
|
+
readonly actorId: string;
|
|
39
|
+
readonly actorType: ActorType;
|
|
40
|
+
readonly tenantId: string;
|
|
41
|
+
readonly spaceId: string;
|
|
42
|
+
readonly requestId: string;
|
|
43
|
+
readonly targets: readonly StoredRecordErasureTarget[];
|
|
44
|
+
}
|
|
45
|
+
interface EraseStoredRecordsInput extends StoredRecordErasureAuthorizationInput {
|
|
46
|
+
/** Target-lock acquisition budget in milliseconds, 1–60000; default 250. */
|
|
47
|
+
readonly lockTimeoutMs?: number;
|
|
48
|
+
/** Rewrite work budget in milliseconds, 1–60000; default 5000. */
|
|
49
|
+
readonly workTimeoutMs?: number;
|
|
50
|
+
/** Synchronous JSON-data transformation. A thrown error or invalid result rolls back the batch. */
|
|
51
|
+
readonly redact: (record: StoredRecordErasureView) => StoredRecordErasureView;
|
|
52
|
+
}
|
|
53
|
+
type StoredRecordErasureOutcome = "erased" | "already_erased" | "active" | "not_found";
|
|
54
|
+
interface EraseStoredRecordsResult {
|
|
55
|
+
targets: Array<StoredRecordErasureTarget & {
|
|
56
|
+
outcome: StoredRecordErasureOutcome;
|
|
57
|
+
}>;
|
|
58
|
+
/** Records processed, including records processed again by repeat erasure. */
|
|
59
|
+
counts: Partial<Record<ErasureRecordKind, number>>;
|
|
60
|
+
}
|
|
61
|
+
interface ErasablePlatformHostStore<TDb> extends PlatformHostStore<TDb> {
|
|
62
|
+
/**
|
|
63
|
+
* Unauthenticated storage port, not an authorization boundary; callers must enforce authorization.
|
|
64
|
+
* Atomic rewrite/marker/audit operation. The audit retains actorId/actorType as identifying metadata.
|
|
65
|
+
* Invocation reads expose storedRecordsErased after commit.
|
|
66
|
+
*/
|
|
67
|
+
eraseStoredRecords(input: EraseStoredRecordsInput): Promise<EraseStoredRecordsResult>;
|
|
68
|
+
}
|
|
69
|
+
interface StoredRecordErasureHost {
|
|
70
|
+
/** Throws StoredRecordErasureAuthorizationError (not_authorized) before store access on authorization refusal. */
|
|
71
|
+
eraseStoredRecords(input: EraseStoredRecordsInput): Promise<EraseStoredRecordsResult>;
|
|
72
|
+
}
|
|
73
|
+
export declare const HOST_RECORDS_ERASED_EVENT: "HostRecordsErased";
|
|
74
|
+
/** Sentinel replacing required payload digests after stored-record erasure. */
|
|
75
|
+
export declare const ERASED_DIGEST: "erased";
|
|
76
|
+
//#endregion
|
|
3
77
|
//#region src/observability.d.ts
|
|
4
78
|
/** Version of the vendor-neutral health/readiness contract. */
|
|
5
79
|
export declare const PLATFORM_HOST_HEALTH_CONTRACT_VERSION: 1;
|
|
@@ -203,30 +277,60 @@ export declare class IdempotencyConflictError extends Error {
|
|
|
203
277
|
export type ActionAdmissionRefusal = "refused" | "failed" | "timed_out" | "invalid_decision" | "invalid_parameters";
|
|
204
278
|
/**
|
|
205
279
|
* Thrown by `submitAction` when a declared admission check did not admit the
|
|
206
|
-
* submission. Host
|
|
207
|
-
*
|
|
208
|
-
*
|
|
209
|
-
*
|
|
280
|
+
* submission. By default Host writes nothing for it. With recordRefusals
|
|
281
|
+
* enabled and an idempotency key, a definitive refusal can be recorded;
|
|
282
|
+
* `recorded` confirms persistence of the terminal refusal. The message holds
|
|
283
|
+
* the action id, the refusal and, for `refused`, the check's fixed code. It omits parameter
|
|
284
|
+
* payloads and caught callback error text.
|
|
210
285
|
*/
|
|
211
286
|
export declare class ActionAdmissionError extends Error {
|
|
212
287
|
readonly actionId: string;
|
|
213
288
|
readonly refusal: ActionAdmissionRefusal;
|
|
214
289
|
/** The check's own code, present only for `refused`. */
|
|
215
290
|
readonly refusalCode?: string | undefined;
|
|
291
|
+
readonly recorded: boolean;
|
|
216
292
|
readonly code: "ACTION_ADMISSION_REFUSED";
|
|
217
293
|
constructor(actionId: string, refusal: ActionAdmissionRefusal,
|
|
218
294
|
/** The check's own code, present only for `refused`. */
|
|
219
|
-
refusalCode?: string | undefined);
|
|
295
|
+
refusalCode?: string | undefined, recorded?: boolean);
|
|
220
296
|
}
|
|
221
297
|
export type SubmissionRefusal = "entitlement" | "authorization";
|
|
222
298
|
/** A definitive authorization-boundary refusal before an invocation is created. */
|
|
223
299
|
export declare class SubmissionRefusalError extends Error {
|
|
224
300
|
readonly actionId: string;
|
|
225
301
|
readonly refusal: SubmissionRefusal;
|
|
302
|
+
readonly recorded: boolean;
|
|
226
303
|
readonly code: "ACTION_SUBMISSION_REFUSED";
|
|
227
|
-
constructor(actionId: string, refusal: SubmissionRefusal, message: string);
|
|
304
|
+
constructor(actionId: string, refusal: SubmissionRefusal, message: string, recorded?: boolean);
|
|
305
|
+
}
|
|
306
|
+
/** Fixed refusal evidence; no submitted values belong in a descriptor. */
|
|
307
|
+
export type SubmissionRefusalDescriptor = {
|
|
308
|
+
class: "entitlement" | "authorization";
|
|
309
|
+
} | {
|
|
310
|
+
class: "admission";
|
|
311
|
+
refusal: "refused" | "invalid_parameters";
|
|
312
|
+
refusalCode?: string;
|
|
313
|
+
};
|
|
314
|
+
/** Minimal identity and evidence for an insert-only, terminal refusal. */
|
|
315
|
+
export interface RecordSubmissionRefusalInput {
|
|
316
|
+
id: string;
|
|
317
|
+
tenantId: string;
|
|
318
|
+
spaceId: string;
|
|
319
|
+
actionId: ActionId;
|
|
320
|
+
actionVersion: number;
|
|
321
|
+
actorId: string;
|
|
322
|
+
actorType: ActorType;
|
|
323
|
+
authorizationBindingId?: string;
|
|
324
|
+
idempotencyKey: string;
|
|
325
|
+
submissionRefusal: SubmissionRefusalDescriptor;
|
|
326
|
+
parameterDigest?: string;
|
|
327
|
+
parameterDigestAlgorithm?: "fabric-canonical-json-sha256-v1";
|
|
328
|
+
correlationId: string;
|
|
329
|
+
causationId?: string;
|
|
330
|
+
createdAt: Date;
|
|
331
|
+
updatedAt: Date;
|
|
228
332
|
}
|
|
229
|
-
export type ExternalCompletionRefusal = "still_executing" | "not_found" | "not_awaiting" | "immediate_contract" | "reference_mismatch" | "provider_mismatch" | "invalid_completion" | "result_invalid" | "redaction_failed";
|
|
333
|
+
export type ExternalCompletionRefusal = "erased" | "still_executing" | "not_found" | "not_awaiting" | "immediate_contract" | "reference_mismatch" | "provider_mismatch" | "invalid_completion" | "result_invalid" | "redaction_failed";
|
|
230
334
|
/**
|
|
231
335
|
* Why a completion was not applied, typed so a webhook handler can answer
|
|
232
336
|
* the external system correctly: `retryable` means the invocation is still
|
|
@@ -292,6 +396,9 @@ export interface HostHitlEvaluatorContext extends AgentActionPolicyContext {
|
|
|
292
396
|
invocation: Readonly<ActionInvocationRecord>;
|
|
293
397
|
}
|
|
294
398
|
export interface ActionInvocationRecord {
|
|
399
|
+
/** Store-owned erasure marker; callers cannot patch it through Host write types. */
|
|
400
|
+
readonly storedRecordsErased?: true;
|
|
401
|
+
submissionRefusal?: SubmissionRefusalDescriptor;
|
|
295
402
|
readonly agentProposal?: AgentProposal;
|
|
296
403
|
id: string;
|
|
297
404
|
tenantId: string;
|
|
@@ -342,7 +449,7 @@ export interface ActionInvocationRecord {
|
|
|
342
449
|
externalCompletion?: RecordedExternalCompletion;
|
|
343
450
|
/** Opaque, non-secret reference used to revalidate delegated execution authority. */
|
|
344
451
|
authorizationBindingId?: string;
|
|
345
|
-
/** Worker claims including the first; approval acceptance sets a minimum of 1. */
|
|
452
|
+
/** Worker claims including the first; inline approval acceptance sets a minimum of 1. Recording preserves the count. */
|
|
346
453
|
attemptCount: number;
|
|
347
454
|
/** Latest claim durably deferred in pre-effect governance; permits only the immediately next claim. */
|
|
348
455
|
deferredBeforeEffectAttempt?: number;
|
|
@@ -405,6 +512,7 @@ export declare const MAX_APPROVAL_EVIDENCE_BYTES: number;
|
|
|
405
512
|
export declare const APPROVAL_REQUESTED_EVENT: "ApprovalRequested";
|
|
406
513
|
export declare const APPROVAL_DECIDED_EVENT: "ApprovalDecided";
|
|
407
514
|
export declare const APPROVAL_EXPIRED_EVENT: "ApprovalExpired";
|
|
515
|
+
export declare const APPROVAL_DECISION_REFUSED_EVENT: "ApprovalDecisionRefused";
|
|
408
516
|
export interface ApprovalRequestedPayload {
|
|
409
517
|
route: AgentActionRoute;
|
|
410
518
|
riskTier: AgentActionRiskTier;
|
|
@@ -435,6 +543,10 @@ export interface ActionApprovalDecision {
|
|
|
435
543
|
}
|
|
436
544
|
export interface PersistedActionApprovalDecision extends Omit<ActionApprovalDecision, "decidedAt"> {
|
|
437
545
|
decidedAt: Date;
|
|
546
|
+
/** Caller-stable identity for the separate recording API; absent on inline and older decisions. */
|
|
547
|
+
requestId?: string;
|
|
548
|
+
/** Claim count when recorded; the next claim is the approved first execution. */
|
|
549
|
+
recordedAtAttempt?: number;
|
|
438
550
|
}
|
|
439
551
|
export interface PolicyEvaluationRecord {
|
|
440
552
|
id: string;
|
|
@@ -554,7 +666,7 @@ export interface AdapterInvocationRecord {
|
|
|
554
666
|
createdAt: Date;
|
|
555
667
|
updatedAt: Date;
|
|
556
668
|
}
|
|
557
|
-
export interface CreateActionInvocationInput extends Omit<ActionInvocationRecord, "createdAt" | "updatedAt" | "attemptCount" | "leaseOwner" | "leaseExpiresAt" | "leaseToken" | "stagedOrigin"> {}
|
|
669
|
+
export interface CreateActionInvocationInput extends Omit<ActionInvocationRecord, "createdAt" | "updatedAt" | "attemptCount" | "leaseOwner" | "leaseExpiresAt" | "leaseToken" | "stagedOrigin" | "storedRecordsErased"> {}
|
|
558
670
|
/** Scope of an adapter checkpoint within its owning action invocation. */
|
|
559
671
|
export interface AdapterInvocationScope {
|
|
560
672
|
tenantId: string;
|
|
@@ -603,6 +715,7 @@ export interface AdapterInvocationWriteInput {
|
|
|
603
715
|
};
|
|
604
716
|
}
|
|
605
717
|
export interface PlatformHostStore<TDb> {
|
|
718
|
+
getSubmissionOutcomeByKey?(key: Readonly<SubmissionOutcomeKey>): Promise<StoredSubmissionOutcomeRecord | undefined>;
|
|
606
719
|
readonly db: TDb;
|
|
607
720
|
/**
|
|
608
721
|
* Run against the store's domain handle. This base seam does not promise a
|
|
@@ -610,7 +723,17 @@ export interface PlatformHostStore<TDb> {
|
|
|
610
723
|
* canonical events, and invocation state must commit atomically.
|
|
611
724
|
*/
|
|
612
725
|
transaction<TResult>(run: (db: TDb) => Promise<TResult>): Promise<TResult>;
|
|
726
|
+
/**
|
|
727
|
+
* First row wins for a supplied idempotency key within tenant, space and action id,
|
|
728
|
+
* including the empty-string key. Replays return the existing row unchanged;
|
|
729
|
+
* the store does not classify submission conflicts (Host does). Unkeyed creates
|
|
730
|
+
* with distinct ids insert independently. `invocationIdempotencyChecks` also
|
|
731
|
+
* covers concurrent key arbitration and preservation of `admittedAt` through
|
|
732
|
+
* an update of another field, plus refusal/admitted arbitration when supported.
|
|
733
|
+
*/
|
|
613
734
|
createActionInvocation(input: CreateActionInvocationInput): Promise<ActionInvocationRecord>;
|
|
735
|
+
/** Insert a refusal or return the key's existing winner unchanged. */
|
|
736
|
+
recordSubmissionRefusal?(input: RecordSubmissionRefusalInput): Promise<ActionInvocationRecord>;
|
|
614
737
|
getActionInvocation(id: string, tenantId: string, spaceId: string): Promise<ActionInvocationRecord | undefined>;
|
|
615
738
|
/** Resolve Host-owned staged identity within one tenant and space. */
|
|
616
739
|
getActionInvocationByStagedOrigin?(tenantId: string, spaceId: string, origin: StagedInvocationOrigin): Promise<ActionInvocationRecord | undefined>;
|
|
@@ -684,8 +807,10 @@ export interface PlatformHostStore<TDb> {
|
|
|
684
807
|
* back when `run` throws.
|
|
685
808
|
*/
|
|
686
809
|
export interface PlatformHostMutationTransaction<TDb> {
|
|
810
|
+
/** Lock due approval candidates in this transaction, skipping locked invocation rows. */
|
|
811
|
+
lockDueApprovals?(input: ExpireDueApprovalsStoreInput): Promise<ActionInvocationRecord[]>;
|
|
687
812
|
/** 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
|
|
813
|
+
beginApprovalDecision?(input: Omit<BeginApprovalDecisionInput<TDb>, "lifecycleEvent">): Promise<ApprovalDecisionTransitionResult>;
|
|
689
814
|
readonly db: TDb;
|
|
690
815
|
/**
|
|
691
816
|
* Read and lock an invocation until this transaction completes.
|
|
@@ -694,9 +819,12 @@ export interface PlatformHostMutationTransaction<TDb> {
|
|
|
694
819
|
getActionInvocationForUpdate?(id: string, tenantId: string, spaceId: string): Promise<ActionInvocationRecord | undefined>;
|
|
695
820
|
/**
|
|
696
821
|
* Read one event by its stable identity inside the transaction.
|
|
822
|
+
* Erasure-capable stores expose storedRecordsErased on rewritten events.
|
|
697
823
|
* Required by serialized saga parent lifecycle transitions.
|
|
698
824
|
*/
|
|
699
|
-
getEvent?(id: string, tenantId: string, spaceId: string): Promise<AssetEventEnvelope
|
|
825
|
+
getEvent?(id: string, tenantId: string, spaceId: string): Promise<(AssetEventEnvelope & {
|
|
826
|
+
readonly storedRecordsErased?: true;
|
|
827
|
+
}) | undefined>;
|
|
700
828
|
/**
|
|
701
829
|
* First-write-wins: an event ID the store already holds, in any tenant or space, is a no-op
|
|
702
830
|
* that keeps the first event. Do not throw, replace or merge it, regardless of
|
|
@@ -747,7 +875,7 @@ export interface PlatformHostMutationTransaction<TDb> {
|
|
|
747
875
|
* governance evidence cannot share the event/verdict transaction.
|
|
748
876
|
*/
|
|
749
877
|
appendExternalReconciliation?: GovernancePlatformHostStore<TDb>["appendExternalReconciliation"];
|
|
750
|
-
/** Atomically retain
|
|
878
|
+
/** Atomically retain a staged batch with the parent mutation; erasure may later rewrite its payloads. */
|
|
751
879
|
stageInvocations?(records: readonly StagedInvocationRecord[]): Promise<void>;
|
|
752
880
|
}
|
|
753
881
|
export type StagedInvocationStatus = "pending" | "dispatched" | "rejected" | "dead_lettered" | "cancelled";
|
|
@@ -970,8 +1098,31 @@ export interface OutboxPlatformHostStore<TDb> extends PlatformHostStore<TDb> {
|
|
|
970
1098
|
* sequences and timestamps and potentially different payloads.
|
|
971
1099
|
*/
|
|
972
1100
|
appendEventWithOutbox(event: AssetEventEnvelope, metadata: OutboxEventMetadata): Promise<void>;
|
|
1101
|
+
/**
|
|
1102
|
+
* `outboxRelayChecks`: claim pending rows available at or before `now` with no
|
|
1103
|
+
* unexpired lease; equality at lease expiry is claimable. Concurrent workers
|
|
1104
|
+
* claim a row once between them. A claim sets owner and expiry to the worker
|
|
1105
|
+
* and `now + leaseDurationMs`, increments attempts by one and increases the
|
|
1106
|
+
* row's token. `limit: 1` returns one row when eligible rows exist.
|
|
1107
|
+
* Published and dead-lettered rows are excluded; returned ordering is unspecified.
|
|
1108
|
+
* `outboxRelayChecks` requires numeric lease tokens that increase on each claim,
|
|
1109
|
+
* including reclaim, despite the optional token fields in the general interfaces.
|
|
1110
|
+
*/
|
|
973
1111
|
claimOutbox(input: ClaimOutboxInput): Promise<OutboxRecord[]>;
|
|
1112
|
+
/**
|
|
1113
|
+
* `outboxRelayChecks`: reject a stale token after reclaim or a wrong worker
|
|
1114
|
+
* without changing the row. With the current owner/token, set `published`
|
|
1115
|
+
* and `publishedAt` and clear lease owner/expiry. A previously settled row
|
|
1116
|
+
* rejects another settlement under its former owner/token.
|
|
1117
|
+
*/
|
|
974
1118
|
markOutboxPublished(id: string, workerId: string, publishedAt: Date, leaseToken?: number): Promise<void>;
|
|
1119
|
+
/**
|
|
1120
|
+
* `outboxRelayChecks`: reject a stale token after reclaim or a wrong worker
|
|
1121
|
+
* without changing the row. With the current owner/token, set `pending` and
|
|
1122
|
+
* the supplied `availableAt`, clear lease owner/expiry and retain attempts;
|
|
1123
|
+
* `deadLetter: true` sets `dead_letter`. A previously settled row rejects
|
|
1124
|
+
* another settlement under its former owner/token.
|
|
1125
|
+
*/
|
|
975
1126
|
markOutboxFailed(input: {
|
|
976
1127
|
id: string;
|
|
977
1128
|
workerId: string;
|
|
@@ -980,6 +1131,13 @@ export interface OutboxPlatformHostStore<TDb> extends PlatformHostStore<TDb> {
|
|
|
980
1131
|
availableAt: Date;
|
|
981
1132
|
deadLetter: boolean;
|
|
982
1133
|
}): Promise<void>;
|
|
1134
|
+
/**
|
|
1135
|
+
* `outboxRelayChecks`: return false for a wrong worker/token or a lease expired
|
|
1136
|
+
* at or before `now`, leaving expiry unchanged. For the current unexpired
|
|
1137
|
+
* owner/token, return true and set expiry to `now + leaseDurationMs`.
|
|
1138
|
+
* When `renewOutboxLeaseAndRead` is present, the same probes expect undefined
|
|
1139
|
+
* on refusal and the renewed record on success.
|
|
1140
|
+
*/
|
|
983
1141
|
renewOutboxLease(input: {
|
|
984
1142
|
id: string;
|
|
985
1143
|
workerId: string;
|
|
@@ -987,6 +1145,14 @@ export interface OutboxPlatformHostStore<TDb> extends PlatformHostStore<TDb> {
|
|
|
987
1145
|
leaseDurationMs: number;
|
|
988
1146
|
now?: Date;
|
|
989
1147
|
}): Promise<boolean>;
|
|
1148
|
+
/** Renew and hydrate the stored envelope atomically for erasure-safe publication. */
|
|
1149
|
+
renewOutboxLeaseAndRead?(input: {
|
|
1150
|
+
id: string;
|
|
1151
|
+
workerId: string;
|
|
1152
|
+
leaseToken: number;
|
|
1153
|
+
leaseDurationMs: number;
|
|
1154
|
+
now?: Date;
|
|
1155
|
+
}): Promise<OutboxRecord | undefined>;
|
|
990
1156
|
listOutbox(input?: {
|
|
991
1157
|
tenantId?: string;
|
|
992
1158
|
spaceId?: string;
|
|
@@ -1120,6 +1286,15 @@ export interface OutboxRequeueAuthorizationInput {
|
|
|
1120
1286
|
* but cannot claim atomic domain-write/event persistence.
|
|
1121
1287
|
*/
|
|
1122
1288
|
export interface AtomicMutationPlatformHostStore<TDb> extends PlatformHostStore<TDb> {
|
|
1289
|
+
/**
|
|
1290
|
+
* Optional retry evidence: reject with ConfirmedTransactionRollback(callbackError)
|
|
1291
|
+
* after rollback succeeds. Its cause must be the identical callback error. A provider
|
|
1292
|
+
* that does not supply this evidence retains the existing failure behavior.
|
|
1293
|
+
* A commit error is not evidence that the callback rolled back. Built-in stores
|
|
1294
|
+
* expose evidence for Host's internal handler callback request; ordinary public
|
|
1295
|
+
* callbacks and store-internal transactions retain their original error objects.
|
|
1296
|
+
* Host normalizes confirmation from custom stores at non-handler transaction sites.
|
|
1297
|
+
*/
|
|
1123
1298
|
transactionWithEvents<TResult>(run: (transaction: PlatformHostMutationTransaction<TDb>) => Promise<TResult>): Promise<TResult>;
|
|
1124
1299
|
}
|
|
1125
1300
|
export interface ApprovalLifecycleEvent {
|
|
@@ -1128,6 +1303,50 @@ export interface ApprovalLifecycleEvent {
|
|
|
1128
1303
|
}
|
|
1129
1304
|
/** Called within the transition transaction. Must be pure and return audit-safe data. Sequence is assigned by the store. */
|
|
1130
1305
|
export type ApprovalLifecycleEventFactory = (invocation: ActionInvocationRecord, kind: "requested" | "decided" | "expired") => ApprovalLifecycleEvent;
|
|
1306
|
+
export interface RecordApprovalDecisionRequest extends ActionApprovalDecision {
|
|
1307
|
+
/** Non-blank caller-stable identifier, at most 256 characters; not trimmed or regenerated by Host. */
|
|
1308
|
+
requestId: string;
|
|
1309
|
+
}
|
|
1310
|
+
export type RecordApprovalDecisionOutcome = "approved" | "denied" | "unauthorized" | "expired" | "already_decided" | "late_terminal" | "not_waiting" | "unsupported";
|
|
1311
|
+
export interface RecordApprovalDecisionResult {
|
|
1312
|
+
outcome: RecordApprovalDecisionOutcome;
|
|
1313
|
+
actionInvocationId: string;
|
|
1314
|
+
status: ActionInvocationRecord["status"];
|
|
1315
|
+
replayed: boolean;
|
|
1316
|
+
/** Included for approved/denied outcomes, including replays; omitted for non-applied outcomes. */
|
|
1317
|
+
decision?: PersistedActionApprovalDecision;
|
|
1318
|
+
}
|
|
1319
|
+
export interface TransactionalApprovalAuthorization<TDb = unknown> {
|
|
1320
|
+
(db: TDb, invocation: Readonly<ActionInvocationRecord>): Promise<boolean>;
|
|
1321
|
+
}
|
|
1322
|
+
export interface RecordApprovalDecisionStoreInput<TDb = unknown> {
|
|
1323
|
+
actionInvocationId: string;
|
|
1324
|
+
tenantId: string;
|
|
1325
|
+
spaceId: string;
|
|
1326
|
+
now: Date;
|
|
1327
|
+
/** Carries no `recordedAtAttempt`: the store assigns it from the locked row. */
|
|
1328
|
+
decision: Omit<PersistedActionApprovalDecision, "recordedAtAttempt"> & {
|
|
1329
|
+
requestId: string;
|
|
1330
|
+
};
|
|
1331
|
+
/** Result of the compatibility authorization boundary evaluated before the transaction. */
|
|
1332
|
+
authorized: boolean;
|
|
1333
|
+
/**
|
|
1334
|
+
* Optional authority check on this transaction's `db`, after the invocation row is locked
|
|
1335
|
+
* and classified as writable, immediately before the decision write.
|
|
1336
|
+
*/
|
|
1337
|
+
authorizeInTransaction?: TransactionalApprovalAuthorization<TDb>;
|
|
1338
|
+
actionKind: "atomic" | "saga" | "unknown";
|
|
1339
|
+
lifecycleEvent?: ApprovalLifecycleEventFactory;
|
|
1340
|
+
/** Called under the invocation lock after any update, with the pre-patch observed row. */
|
|
1341
|
+
attemptEvent?: (invocation: ActionInvocationRecord, outcome: RecordApprovalDecisionOutcome) => ApprovalLifecycleEvent;
|
|
1342
|
+
}
|
|
1343
|
+
export interface RecordApprovalDecisionStoreResult {
|
|
1344
|
+
/** Whether this transaction changed the invocation; false for replays and previously expired rows. */
|
|
1345
|
+
applied: boolean;
|
|
1346
|
+
outcome: RecordApprovalDecisionOutcome;
|
|
1347
|
+
invocation: ActionInvocationRecord;
|
|
1348
|
+
replayed: boolean;
|
|
1349
|
+
}
|
|
1131
1350
|
export interface ExpireDueApprovalsInput {
|
|
1132
1351
|
tenantId?: string;
|
|
1133
1352
|
spaceId?: string;
|
|
@@ -1148,7 +1367,7 @@ export interface ParkApprovalInput {
|
|
|
1148
1367
|
leaseToken?: number;
|
|
1149
1368
|
lifecycleEvent?: ApprovalLifecycleEventFactory;
|
|
1150
1369
|
}
|
|
1151
|
-
export interface BeginApprovalDecisionInput {
|
|
1370
|
+
export interface BeginApprovalDecisionInput<TDb = unknown> {
|
|
1152
1371
|
lifecycleEvent?: ApprovalLifecycleEventFactory;
|
|
1153
1372
|
actionInvocationId: string;
|
|
1154
1373
|
tenantId: string;
|
|
@@ -1157,15 +1376,26 @@ export interface BeginApprovalDecisionInput {
|
|
|
1157
1376
|
leaseOwner: string;
|
|
1158
1377
|
leaseDurationMs: number;
|
|
1159
1378
|
now: Date;
|
|
1379
|
+
/**
|
|
1380
|
+
* Optional authority check on this transaction's `db`, after the invocation row is locked
|
|
1381
|
+
* and classified as writable, immediately before the decision write.
|
|
1382
|
+
*/
|
|
1383
|
+
authorizeInTransaction?: TransactionalApprovalAuthorization<TDb>;
|
|
1160
1384
|
}
|
|
1161
1385
|
export interface ApprovalDecisionTransitionResult {
|
|
1162
1386
|
applied: boolean;
|
|
1163
1387
|
invocation?: ActionInvocationRecord;
|
|
1388
|
+
/** True when a configured in-transaction authority check refused the decision. */
|
|
1389
|
+
authorizationDenied?: boolean;
|
|
1164
1390
|
}
|
|
1165
|
-
/**
|
|
1391
|
+
/** Approval persistence capabilities used by Host HITL, inline resume and decision recording. */
|
|
1166
1392
|
export interface ApprovalPlatformHostStore<TDb> extends PlatformHostStore<TDb> {
|
|
1393
|
+
/** Serialize classification, optional events/outbox and the queued/terminal transition in one transaction. */
|
|
1394
|
+
recordApprovalDecision?(input: RecordApprovalDecisionStoreInput<TDb>): Promise<RecordApprovalDecisionStoreResult>;
|
|
1167
1395
|
/** True only when approval transitions and lifecycle outbox events share a transaction. */
|
|
1168
1396
|
readonly transactionalApprovalLifecycle?: boolean;
|
|
1397
|
+
/** True only when approval authority callbacks run under the locked row in the decision transaction. */
|
|
1398
|
+
readonly transactionalApprovalAuthorization?: boolean;
|
|
1169
1399
|
/**
|
|
1170
1400
|
* Conditionally park an executable invocation only with its matching lease owner/generation
|
|
1171
1401
|
* (when leased) and no prior approval decision. Persist the deadline supplied in input.
|
|
@@ -1195,7 +1425,7 @@ export interface ApprovalPlatformHostStore<TDb> extends PlatformHostStore<TDb> {
|
|
|
1195
1425
|
* or expired event/outbox writes and state change must commit in the same atomic unit
|
|
1196
1426
|
* of work, or roll back together. Required when implementing parkApproval/expireDueApprovals.
|
|
1197
1427
|
*/
|
|
1198
|
-
beginApprovalDecision(input: BeginApprovalDecisionInput): Promise<ApprovalDecisionTransitionResult>;
|
|
1428
|
+
beginApprovalDecision(input: BeginApprovalDecisionInput<TDb>): Promise<ApprovalDecisionTransitionResult>;
|
|
1199
1429
|
}
|
|
1200
1430
|
/** Optional durable capabilities used when external-governance enrichment is configured. */
|
|
1201
1431
|
export interface GovernancePlatformHostStore<TDb> extends PlatformHostStore<TDb> {
|
|
@@ -1294,6 +1524,10 @@ export interface ActionExecutionAuthorizationInput extends ActionAuthorizationIn
|
|
|
1294
1524
|
invocation: Readonly<ActionInvocationRecord>;
|
|
1295
1525
|
executionReason: ActionExecutionReason;
|
|
1296
1526
|
}
|
|
1527
|
+
/** Execution authorization input evaluated on the handler transaction's domain handle. */
|
|
1528
|
+
export interface ActionExecutionAuthorizationInTransactionInput<TDb> extends ActionExecutionAuthorizationInput {
|
|
1529
|
+
db: TDb;
|
|
1530
|
+
}
|
|
1297
1531
|
/** Trusted authorization input for deciding a parked approval. */
|
|
1298
1532
|
export interface ActionApprovalAuthorizationInput extends ActionAuthorizationInput {
|
|
1299
1533
|
decision: ActionApprovalDecision;
|
|
@@ -1302,6 +1536,10 @@ export interface ActionApprovalAuthorizationInput extends ActionAuthorizationInp
|
|
|
1302
1536
|
/** The durable (post-redaction) invocation record as read before the decision transition. */
|
|
1303
1537
|
invocation: Readonly<ActionInvocationRecord>;
|
|
1304
1538
|
}
|
|
1539
|
+
/** Approval authorization input evaluated while the invocation row is locked for its decision write. */
|
|
1540
|
+
export interface ActionApprovalAuthorizationInTransactionInput<TDb> extends ActionApprovalAuthorizationInput {
|
|
1541
|
+
db: TDb;
|
|
1542
|
+
}
|
|
1305
1543
|
/**
|
|
1306
1544
|
* Input to `resolvePolicies`. Carries the invocation identity and the
|
|
1307
1545
|
* schema-parsed durable (post-redaction) parameters so a resolver can choose
|
|
@@ -1312,7 +1550,7 @@ export interface ActionApprovalAuthorizationInput extends ActionAuthorizationInp
|
|
|
1312
1550
|
export interface ResolvePoliciesInput extends ActionExecutionAuthorizationInput {
|
|
1313
1551
|
declaredPolicyIds: readonly string[];
|
|
1314
1552
|
}
|
|
1315
|
-
export interface PlatformHostAuthorization {
|
|
1553
|
+
export interface PlatformHostAuthorization<TDb = unknown> {
|
|
1316
1554
|
checkEntitlement(input: ActionAuthorizationInput): Promise<boolean>;
|
|
1317
1555
|
authorize(input: ActionAuthorizationInput): Promise<boolean>;
|
|
1318
1556
|
/**
|
|
@@ -1320,14 +1558,25 @@ export interface PlatformHostAuthorization {
|
|
|
1320
1558
|
* execution. When absent, the Host reuses `authorize` at this boundary.
|
|
1321
1559
|
*/
|
|
1322
1560
|
authorizeExecution?(input: ActionExecutionAuthorizationInput): Promise<boolean>;
|
|
1561
|
+
/** Optional final execution authority check on the handler transaction, immediately before the effect. */
|
|
1562
|
+
authorizeExecutionInTransaction?(input: ActionExecutionAuthorizationInTransactionInput<TDb>): Promise<boolean>;
|
|
1323
1563
|
/** Optional distinct authorization boundary for human/system approval decisions. */
|
|
1324
1564
|
authorizeApproval?(input: ActionApprovalAuthorizationInput): Promise<boolean>;
|
|
1565
|
+
/** Optional final approval authority check under the locked row in the decision transaction. */
|
|
1566
|
+
authorizeApprovalInTransaction?(input: ActionApprovalAuthorizationInTransactionInput<TDb>): Promise<boolean>;
|
|
1325
1567
|
/**
|
|
1326
1568
|
* Authorization for `requeueOutboxDeadLetter`. There is no action to fall
|
|
1327
1569
|
* back to, so when this is absent every requeue is refused as
|
|
1328
1570
|
* `not_authorized`. A throw propagates and nothing is requeued.
|
|
1329
1571
|
*/
|
|
1330
1572
|
authorizeOutboxRequeue?(input: OutboxRequeueAuthorizationInput): Promise<boolean>;
|
|
1573
|
+
/**
|
|
1574
|
+
* Erasure operator authorization after validation and before store access. No fallback:
|
|
1575
|
+
* absence or a result other than true raises StoredRecordErasureAuthorizationError.
|
|
1576
|
+
* A thrown hook error propagates unchanged; neither outcome reaches the store.
|
|
1577
|
+
* Receives identifying facts and detached validated targets, without redact or stored payloads.
|
|
1578
|
+
*/
|
|
1579
|
+
authorizeStoredRecordErasure?(input: StoredRecordErasureAuthorizationInput): Promise<boolean>;
|
|
1331
1580
|
}
|
|
1332
1581
|
export interface DispatchActionInput {
|
|
1333
1582
|
actionInvocationId: string;
|
|
@@ -1497,7 +1746,7 @@ export interface ErrorTextRedactionContext {
|
|
|
1497
1746
|
}
|
|
1498
1747
|
export interface PlatformHostOptions<TDb> {
|
|
1499
1748
|
store: PlatformHostStore<TDb>;
|
|
1500
|
-
authorization: PlatformHostAuthorization
|
|
1749
|
+
authorization: PlatformHostAuthorization<TDb>;
|
|
1501
1750
|
/** Preferred explicit catalog assembled from this runtime's Fabric modules. */
|
|
1502
1751
|
registry?: Pick<ModuleRegistry<TDb>, "resolveAction" | "resolvePolicy" | "resolveStateMachine"> & Partial<Pick<ModuleRegistry<TDb>, "orderedModules">>;
|
|
1503
1752
|
/** Resolve vertical- or runtime-local actions without mutating the process-wide registry. */
|
|
@@ -1532,9 +1781,29 @@ export interface PlatformHostOptions<TDb> {
|
|
|
1532
1781
|
* approval resume, exhausted attempts, and marker-write failures are not retried.
|
|
1533
1782
|
* Policy persistence, obligation listing/resolution/persistence, state-machine checks,
|
|
1534
1783
|
* the handler transaction, handlers, adapters, and finalization are excluded;
|
|
1535
|
-
* their failure/reconciliation/recovery semantics apply,
|
|
1784
|
+
* their separate failure/reconciliation/recovery semantics apply, including handlerRetry
|
|
1785
|
+
* for confirmed handler rollback, subject to recoveryMaxAttempts.
|
|
1536
1786
|
*/
|
|
1537
1787
|
retryableExecutionMaxAttempts?: number;
|
|
1788
|
+
/** Bounded retries within one execution attempt after confirmed handler rollback. */
|
|
1789
|
+
handlerRetry?: {
|
|
1790
|
+
/** Total transaction tries, including the first; integer 1–10, default 3. One disables retry. */
|
|
1791
|
+
maxAttempts?: number;
|
|
1792
|
+
/** Assert the whole retried unit kept effects in the transaction. Literal true opts in; throws refuse retry. */
|
|
1793
|
+
classify?: (error: unknown, context: {
|
|
1794
|
+
actionId: string;
|
|
1795
|
+
}) => boolean;
|
|
1796
|
+
/** Retry number starts at 1. Default full jitter on 25 ms doubling; clamped to 0–1000 ms. Throws/non-finite stop retry. */
|
|
1797
|
+
delayMs?: number | ((retry: number) => number);
|
|
1798
|
+
/** Called before each delay; attempt is the upcoming try (2..maxAttempts). Sync throws and async rejections are ignored without awaiting. */
|
|
1799
|
+
onRetry?: (info: {
|
|
1800
|
+
actionInvocationId: string;
|
|
1801
|
+
actionId: string;
|
|
1802
|
+
attempt: number;
|
|
1803
|
+
maxAttempts: number;
|
|
1804
|
+
error: unknown;
|
|
1805
|
+
}) => void;
|
|
1806
|
+
};
|
|
1538
1807
|
/**
|
|
1539
1808
|
* Positive integer cap on worker claims for resumed leased running invocations
|
|
1540
1809
|
* including the first (default max(5, retryableExecutionMaxAttempts); Infinity is rejected).
|
|
@@ -1550,6 +1819,8 @@ export interface PlatformHostOptions<TDb> {
|
|
|
1550
1819
|
services?: FabricRuntimeServices;
|
|
1551
1820
|
idempotency?: {
|
|
1552
1821
|
conflictMode?: "audit-only" | "enforce";
|
|
1822
|
+
/** Reserve keyed definitive submission refusals. Requires enforcing identity and store support. */
|
|
1823
|
+
recordRefusals?: boolean;
|
|
1553
1824
|
onConflict?(conflict: IdempotencyConflict): void;
|
|
1554
1825
|
onLegacyRecord?(invocation: ActionInvocationRecord): void;
|
|
1555
1826
|
};
|
|
@@ -1581,6 +1852,8 @@ export interface PlatformHostOptions<TDb> {
|
|
|
1581
1852
|
approvalDefaultTtlMs?: number;
|
|
1582
1853
|
/** Atomic approval lifecycle events and outbox writes; defaults to false. */
|
|
1583
1854
|
approvalLifecycleEvents?: boolean;
|
|
1855
|
+
/** Atomic audit events for refused recording attempts; defaults to false. */
|
|
1856
|
+
approvalDecisionAttemptEvents?: boolean;
|
|
1584
1857
|
/** Durable evaluator/ruleset version recorded with every HITL decision. */
|
|
1585
1858
|
hitlPolicyVersion?: string;
|
|
1586
1859
|
/** Optional portable resolver; provider-specific implementations belong in integration packages. */
|
|
@@ -1696,6 +1969,10 @@ export interface PlatformHostOptions<TDb> {
|
|
|
1696
1969
|
*/
|
|
1697
1970
|
adapterDeadlineMs?: number;
|
|
1698
1971
|
}
|
|
1972
|
+
/** Additive capability; handwritten GovernedActionHost implementations retain their existing shape. */
|
|
1973
|
+
export interface ApprovalDecisionRecordingHost {
|
|
1974
|
+
recordApprovalDecision(id: string, tenantId: string, spaceId: string, request: RecordApprovalDecisionRequest): Promise<RecordApprovalDecisionResult>;
|
|
1975
|
+
}
|
|
1699
1976
|
export interface ApprovalExpiryHost {
|
|
1700
1977
|
expireDueApprovals(input?: ExpireDueApprovalsInput): Promise<{
|
|
1701
1978
|
expired: string[];
|
|
@@ -1747,20 +2024,59 @@ export interface OutboxRequeueHost {
|
|
|
1747
2024
|
*/
|
|
1748
2025
|
requeueOutboxDeadLetter(input: RequeueOutboxDeadLetterInput): Promise<RequeueOutboxDeadLetterResult>;
|
|
1749
2026
|
}
|
|
2027
|
+
/** Exact durable key scope; an empty idempotency key is valid. */
|
|
2028
|
+
export interface SubmissionOutcomeKey {
|
|
2029
|
+
tenantId: string;
|
|
2030
|
+
spaceId: string;
|
|
2031
|
+
actionId: ActionId;
|
|
2032
|
+
idempotencyKey: string;
|
|
2033
|
+
}
|
|
2034
|
+
export type StoredSubmissionOutcomeRecord = Readonly<SubmissionOutcomeKey & Pick<ActionInvocationRecord, "id" | "actionVersion" | "actorId" | "actorType" | "authorizationBindingId" | "idempotencyActorId" | "idempotencyAuthorizationBindingId" | "status" | "submissionRefusal" | "storedRecordsErased">>;
|
|
2035
|
+
export interface ReadSubmissionOutcomeInput extends SubmissionOutcomeKey {
|
|
2036
|
+
actorId: string;
|
|
2037
|
+
actorType: ActorType;
|
|
2038
|
+
authorizationBindingId?: string;
|
|
2039
|
+
}
|
|
2040
|
+
type ReceiptIdentity = {
|
|
2041
|
+
actionInvocationId: string;
|
|
2042
|
+
actionVersion: number;
|
|
2043
|
+
};
|
|
2044
|
+
export type ReadSubmissionOutcomeResult = {
|
|
2045
|
+
kind: "no_record";
|
|
2046
|
+
} | (ReceiptIdentity & {
|
|
2047
|
+
kind: "submission_refused";
|
|
2048
|
+
submissionRefusal: SubmissionRefusalDescriptor;
|
|
2049
|
+
}) | (ReceiptIdentity & {
|
|
2050
|
+
kind: "invocation";
|
|
2051
|
+
status: Exclude<ActionStatus, "submission_refused">;
|
|
2052
|
+
}) | (ReceiptIdentity & {
|
|
2053
|
+
kind: "records_erased";
|
|
2054
|
+
recordedStatus: ActionStatus;
|
|
2055
|
+
});
|
|
2056
|
+
export interface SubmissionOutcomeReader {
|
|
2057
|
+
readSubmissionOutcome(input: Readonly<ReadSubmissionOutcomeInput>): Promise<ReadSubmissionOutcomeResult>;
|
|
2058
|
+
}
|
|
1750
2059
|
//#endregion
|
|
1751
2060
|
//#region src/host.d.ts
|
|
1752
|
-
export declare function createGovernedActionHost<TDb>(options: PlatformHostOptions<TDb>): GovernedActionHost & OutboxRequeueHost & ApprovalExpiryHost;
|
|
2061
|
+
export declare function createGovernedActionHost<TDb>(options: PlatformHostOptions<TDb>): SubmissionOutcomeReader & GovernedActionHost & OutboxRequeueHost & ApprovalExpiryHost & ApprovalDecisionRecordingHost & StoredRecordErasureHost;
|
|
1753
2062
|
//#endregion
|
|
1754
2063
|
//#region src/memory-store.d.ts
|
|
2064
|
+
/**
|
|
2065
|
+
* Optional domain snapshot/restore binder. The Host handler callback can request
|
|
2066
|
+
* rollback confirmation after a failed callback and successful undo/restore.
|
|
2067
|
+
* Commit failures and providerless internal transactions supply no confirmation.
|
|
2068
|
+
* Ordinary public transaction callbacks retain their original error objects.
|
|
2069
|
+
*/
|
|
1755
2070
|
export interface MemoryPlatformHostTransactionProvider<TDb> {
|
|
1756
2071
|
snapshot(db: TDb): TDb;
|
|
1757
2072
|
restore(db: TDb, snapshot: TDb): void;
|
|
1758
2073
|
}
|
|
1759
|
-
export declare class MemoryPlatformHostStore<TDb> implements RecoverablePlatformHostStore<TDb>, ApprovalPlatformHostStore<TDb>, GovernancePlatformHostStore<TDb>, OutboxPlatformHostStore<TDb>, OutboxRequeuePlatformHostStore<TDb>, StagedInvocationPlatformHostStore<TDb> {
|
|
2074
|
+
export declare class MemoryPlatformHostStore<TDb> implements ErasablePlatformHostStore<TDb>, RecoverablePlatformHostStore<TDb>, ApprovalPlatformHostStore<TDb>, GovernancePlatformHostStore<TDb>, OutboxPlatformHostStore<TDb>, OutboxRequeuePlatformHostStore<TDb>, StagedInvocationPlatformHostStore<TDb> {
|
|
1760
2075
|
readonly db: TDb;
|
|
2076
|
+
getSubmissionOutcomeByKey(key: Readonly<SubmissionOutcomeKey>): Promise<StoredSubmissionOutcomeRecord | undefined>;
|
|
1761
2077
|
readonly transactionalOutbox: boolean;
|
|
1762
2078
|
readonly transactionalApprovalLifecycle: boolean;
|
|
1763
|
-
|
|
2079
|
+
readonly transactionalApprovalAuthorization = true;
|
|
1764
2080
|
readonly transactionalStagedInvocations: boolean;
|
|
1765
2081
|
transactionWithEvents?: <TResult>(run: (transaction: PlatformHostMutationTransaction<TDb>) => Promise<TResult>) => Promise<TResult>;
|
|
1766
2082
|
private adapterCommit;
|
|
@@ -1781,10 +2097,16 @@ export declare class MemoryPlatformHostStore<TDb> implements RecoverablePlatform
|
|
|
1781
2097
|
* `private`, as for the store's other internals, is a compile-time guard.
|
|
1782
2098
|
*/
|
|
1783
2099
|
private readonly outboxRequeues;
|
|
2100
|
+
private readonly erasedStages;
|
|
2101
|
+
private readonly erasureMarkers;
|
|
2102
|
+
private isErased;
|
|
2103
|
+
private assertNotErased;
|
|
2104
|
+
eraseStoredRecords(request: EraseStoredRecordsInput): Promise<EraseStoredRecordsResult>;
|
|
1784
2105
|
constructor(db: TDb, transactionProvider?: MemoryPlatformHostTransactionProvider<TDb>);
|
|
1785
2106
|
transaction<TResult>(run: (db: TDb) => Promise<TResult>): Promise<TResult>;
|
|
1786
2107
|
private runTransactionWithEvents;
|
|
1787
2108
|
createActionInvocation(input: CreateActionInvocationInput): Promise<ActionInvocationRecord>;
|
|
2109
|
+
recordSubmissionRefusal(input: RecordSubmissionRefusalInput): Promise<ActionInvocationRecord>;
|
|
1788
2110
|
createActionInvocationForStagedLease(input: CreateStagedActionInvocationInput): Promise<CreateStagedActionInvocationResult>;
|
|
1789
2111
|
private applyStagedBatch;
|
|
1790
2112
|
getActionInvocation(id: string, tenantId: string, spaceId: string): Promise<ActionInvocationRecord | undefined>;
|
|
@@ -1793,7 +2115,8 @@ export declare class MemoryPlatformHostStore<TDb> implements RecoverablePlatform
|
|
|
1793
2115
|
recordHitlDecision(actionInvocationId: string, tenantId: string, spaceId: string, decision: HitlDecisionEvidence): Promise<ActionInvocationRecord>;
|
|
1794
2116
|
private runApprovalTransaction;
|
|
1795
2117
|
parkApproval(input: ParkApprovalInput): Promise<ApprovalDecisionTransitionResult>;
|
|
1796
|
-
|
|
2118
|
+
recordApprovalDecision(input: RecordApprovalDecisionStoreInput<TDb>): Promise<RecordApprovalDecisionStoreResult>;
|
|
2119
|
+
beginApprovalDecision(input: BeginApprovalDecisionInput<TDb>): Promise<ApprovalDecisionTransitionResult>;
|
|
1797
2120
|
expireDueApprovals(input: ExpireDueApprovalsStoreInput): Promise<ActionInvocationRecord[]>;
|
|
1798
2121
|
appendPolicyEvaluation(record: PolicyEvaluationRecord): Promise<void>;
|
|
1799
2122
|
recordMutationGovernance(actionInvocationId: string, tenantId: string, spaceId: string, context: Pick<ActionInvocationRecord, "mutationFootprint" | "executionPrincipal"> & {
|
|
@@ -1824,13 +2147,14 @@ export declare class MemoryPlatformHostStore<TDb> implements RecoverablePlatform
|
|
|
1824
2147
|
availableAt: Date;
|
|
1825
2148
|
deadLetter: boolean;
|
|
1826
2149
|
}): Promise<void>;
|
|
1827
|
-
renewOutboxLease(input:
|
|
2150
|
+
renewOutboxLease(input: Parameters<OutboxPlatformHostStore<TDb>["renewOutboxLease"]>[0]): Promise<boolean>;
|
|
2151
|
+
renewOutboxLeaseAndRead(input: {
|
|
1828
2152
|
id: string;
|
|
1829
2153
|
workerId: string;
|
|
1830
2154
|
leaseToken: number;
|
|
1831
2155
|
leaseDurationMs: number;
|
|
1832
2156
|
now?: Date;
|
|
1833
|
-
}): Promise<
|
|
2157
|
+
}): Promise<OutboxRecord | undefined>;
|
|
1834
2158
|
listOutbox(input?: {
|
|
1835
2159
|
tenantId?: string;
|
|
1836
2160
|
spaceId?: string;
|
|
@@ -1972,21 +2296,38 @@ export interface PostgresPlatformHostTransactionContext<TDb> {
|
|
|
1972
2296
|
* `pg.PoolClient`. Production applications provide this adapter so domain
|
|
1973
2297
|
* methods and Host ledger writes share one PostgreSQL transaction.
|
|
1974
2298
|
*/
|
|
2299
|
+
/**
|
|
2300
|
+
* May reject with ConfirmedTransactionRollback(callbackError) after successful rollback
|
|
2301
|
+
* of a failed callback. Providers omitting that evidence get no in-attempt handler retry.
|
|
2302
|
+
* Commit errors must not be represented as confirmed callback rollback. The store exposes
|
|
2303
|
+
* evidence at the Host handler callback request and normalizes it for other consumers.
|
|
2304
|
+
*/
|
|
1975
2305
|
export interface PostgresPlatformHostTransactionProvider<TDb> {
|
|
1976
2306
|
run<TResult>(run: (context: PostgresPlatformHostTransactionContext<TDb>) => Promise<TResult>): Promise<TResult>;
|
|
1977
2307
|
}
|
|
1978
2308
|
/** 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> {
|
|
2309
|
+
export declare class PostgresPlatformHostStore<TDb> implements ErasablePlatformHostStore<TDb>, RecoverablePlatformHostStore<TDb>, ApprovalPlatformHostStore<TDb>, GovernancePlatformHostStore<TDb>, OutboxPlatformHostStore<TDb>, OutboxRequeuePlatformHostStore<TDb>, StagedInvocationPlatformHostStore<TDb> {
|
|
1980
2310
|
readonly db: TDb;
|
|
1981
2311
|
private readonly sql;
|
|
2312
|
+
private readonly transactionProvider?;
|
|
1982
2313
|
readonly transactionWithEvents?: AtomicMutationPlatformHostStore<TDb>["transactionWithEvents"];
|
|
2314
|
+
private ownerLocksPersist;
|
|
2315
|
+
private readonly lockedOwners;
|
|
1983
2316
|
readonly transactionalOutbox: boolean;
|
|
1984
2317
|
readonly transactionalApprovalLifecycle: boolean;
|
|
2318
|
+
readonly transactionalApprovalAuthorization: boolean;
|
|
1985
2319
|
readonly transactionalStagedInvocations: boolean;
|
|
1986
|
-
constructor(db: TDb, sql: PlatformHostSqlClient, transactionProvider?: PostgresPlatformHostTransactionProvider<TDb>);
|
|
2320
|
+
constructor(db: TDb, sql: PlatformHostSqlClient, transactionProvider?: PostgresPlatformHostTransactionProvider<TDb> | undefined);
|
|
2321
|
+
/** Internal provider entry: non-handler consumers retain their original error objects. */
|
|
2322
|
+
private runTransaction;
|
|
2323
|
+
private refuseErased;
|
|
2324
|
+
private ownerFence;
|
|
1987
2325
|
ensureSchema(): Promise<void>;
|
|
2326
|
+
eraseStoredRecords(request: EraseStoredRecordsInput): Promise<EraseStoredRecordsResult>;
|
|
1988
2327
|
transaction<TResult>(run: (db: TDb) => Promise<TResult>): Promise<TResult>;
|
|
2328
|
+
getSubmissionOutcomeByKey(key: Readonly<SubmissionOutcomeKey>): Promise<StoredSubmissionOutcomeRecord | undefined>;
|
|
1989
2329
|
createActionInvocation(input: CreateActionInvocationInput): Promise<ActionInvocationRecord>;
|
|
2330
|
+
recordSubmissionRefusal(input: RecordSubmissionRefusalInput): Promise<ActionInvocationRecord>;
|
|
1990
2331
|
createActionInvocationForStagedLease(input: CreateStagedActionInvocationInput): Promise<CreateStagedActionInvocationResult>;
|
|
1991
2332
|
stageInvocations(records: readonly StagedInvocationRecord[]): Promise<void>;
|
|
1992
2333
|
getActionInvocation(id: string, tenantId: string, spaceId: string): Promise<ActionInvocationRecord | undefined>;
|
|
@@ -1995,7 +2336,9 @@ export declare class PostgresPlatformHostStore<TDb> implements RecoverablePlatfo
|
|
|
1995
2336
|
recordHitlDecision(actionInvocationId: string, tenantId: string, spaceId: string, decision: HitlDecisionEvidence): Promise<ActionInvocationRecord>;
|
|
1996
2337
|
parkApproval(input: ParkApprovalInput): Promise<ApprovalDecisionTransitionResult>;
|
|
1997
2338
|
expireDueApprovals(input: ExpireDueApprovalsStoreInput): Promise<ActionInvocationRecord[]>;
|
|
1998
|
-
|
|
2339
|
+
private lockDueApprovals;
|
|
2340
|
+
recordApprovalDecision(input: RecordApprovalDecisionStoreInput<TDb>): Promise<RecordApprovalDecisionStoreResult>;
|
|
2341
|
+
beginApprovalDecision(input: BeginApprovalDecisionInput<TDb>): Promise<ApprovalDecisionTransitionResult>;
|
|
1999
2342
|
appendPolicyEvaluation(record: PolicyEvaluationRecord): Promise<void>;
|
|
2000
2343
|
recordMutationGovernance(actionInvocationId: string, tenantId: string, spaceId: string, context: {
|
|
2001
2344
|
footprint: NonNullable<ActionInvocationRecord["mutationFootprint"]>;
|
|
@@ -2024,13 +2367,14 @@ export declare class PostgresPlatformHostStore<TDb> implements RecoverablePlatfo
|
|
|
2024
2367
|
availableAt: Date;
|
|
2025
2368
|
deadLetter: boolean;
|
|
2026
2369
|
}): Promise<void>;
|
|
2027
|
-
renewOutboxLease(input:
|
|
2370
|
+
renewOutboxLease(input: Parameters<OutboxPlatformHostStore<TDb>["renewOutboxLease"]>[0]): Promise<boolean>;
|
|
2371
|
+
renewOutboxLeaseAndRead(input: {
|
|
2028
2372
|
id: string;
|
|
2029
2373
|
workerId: string;
|
|
2030
2374
|
leaseToken: number;
|
|
2031
2375
|
leaseDurationMs: number;
|
|
2032
2376
|
now?: Date;
|
|
2033
|
-
}): Promise<
|
|
2377
|
+
}): Promise<OutboxRecord | undefined>;
|
|
2034
2378
|
listOutbox(input?: {
|
|
2035
2379
|
tenantId?: string;
|
|
2036
2380
|
spaceId?: string;
|
|
@@ -2115,7 +2459,9 @@ export declare class PostgresPlatformHostStore<TDb> implements RecoverablePlatfo
|
|
|
2115
2459
|
updateLeasedActionInvocation(input: UpdateLeasedActionInvocationInput): Promise<boolean>;
|
|
2116
2460
|
renewActionInvocationLease(input: RenewActionInvocationLeaseInput): Promise<boolean>;
|
|
2117
2461
|
listEvents(tenantId: string, spaceId: string): Promise<AssetEventEnvelope[]>;
|
|
2118
|
-
getEvent(id: string, tenantId: string, spaceId: string): Promise<AssetEventEnvelope
|
|
2462
|
+
getEvent(id: string, tenantId: string, spaceId: string): Promise<(AssetEventEnvelope & {
|
|
2463
|
+
readonly storedRecordsErased?: true;
|
|
2464
|
+
}) | undefined>;
|
|
2119
2465
|
}
|
|
2120
2466
|
//#endregion
|
|
2121
2467
|
//#region src/postgres-migrations.d.ts
|
|
@@ -2259,6 +2605,11 @@ export declare function prepareStagedInvocationBatch<TDb>(input: PrepareStagedIn
|
|
|
2259
2605
|
export declare function stagedInvocationRequestIdentity(record: StagedInvocationRecord): string;
|
|
2260
2606
|
export declare function cloneStagedInvocationRecord(record: StagedInvocationRecord): StagedInvocationRecord;
|
|
2261
2607
|
export declare function asStagedInvocationStore<TDb>(store: PlatformHostStore<TDb>): StagedInvocationPlatformHostStore<TDb> | undefined;
|
|
2608
|
+
/** Placeholder for published payload-covering batch digests replaced by migration 16. */
|
|
2609
|
+
export declare const LEGACY_BATCH_DIGEST = "legacy-batch";
|
|
2610
|
+
/** Replay comparison used by both built-in stores. Compares the full request identity,
|
|
2611
|
+
* skipping only the batch-digest comparison when the stored row carries LEGACY_BATCH_DIGEST. */
|
|
2612
|
+
export declare function stagedInvocationRequestMatches(stored: StagedInvocationRecord, incoming: StagedInvocationRecord): boolean;
|
|
2262
2613
|
//#endregion
|
|
2263
2614
|
//#region src/tenant-isolation.d.ts
|
|
2264
2615
|
export interface TenantIsolationScope {
|
|
@@ -2291,13 +2642,13 @@ export interface TenantIsolationSubject<TDb = unknown> {
|
|
|
2291
2642
|
}>;
|
|
2292
2643
|
/**
|
|
2293
2644
|
* Optional: put the host and store back to a known state before a check.
|
|
2294
|
-
* The checks tolerate accumulated state, and
|
|
2295
|
-
*
|
|
2645
|
+
* The checks tolerate accumulated state, and direct probes use terminal rows
|
|
2646
|
+
* or retire the active rows they create, so this exists for subjects whose store is shared.
|
|
2296
2647
|
*/
|
|
2297
2648
|
reset?(): Promise<void> | void;
|
|
2298
2649
|
}
|
|
2299
2650
|
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";
|
|
2651
|
+
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
2652
|
run(subject: TenantIsolationSubject): Promise<string[]>;
|
|
2302
2653
|
}
|
|
2303
2654
|
export interface TenantIsolationResult {
|
|
@@ -2312,9 +2663,10 @@ export interface TenantIsolationResult {
|
|
|
2312
2663
|
/**
|
|
2313
2664
|
* The suite a deployment of the host must pass before it claims isolation.
|
|
2314
2665
|
*
|
|
2315
|
-
*
|
|
2666
|
+
* Ten checks: an invocation cannot be read, executed, or completed under
|
|
2316
2667
|
* another tenant's scope; an idempotency key is a tenant's own, so the same
|
|
2317
|
-
* key in two tenants is two invocations;
|
|
2668
|
+
* key in two tenants is two invocations; optional recorded refusals retain
|
|
2669
|
+
* tenant and space scope, including when ordinary creation encounters a refusal; a tenant's event stream carries no
|
|
2318
2670
|
* other tenant's events; a worker scoped to one tenant does not claim another's
|
|
2319
2671
|
* work; staged listing and claiming retain tenant and space scope; an adapter
|
|
2320
2672
|
* checkpoint cannot be read or written under another tenant, space, or owning
|
|
@@ -2401,4 +2753,224 @@ export declare function eventAppendChecks(): readonly EventAppendCheck[];
|
|
|
2401
2753
|
*/
|
|
2402
2754
|
export declare function runEventAppendChecks<TDb>(subject: EventAppendSubject<TDb>): Promise<EventAppendResult>;
|
|
2403
2755
|
//#endregion
|
|
2404
|
-
|
|
2756
|
+
//#region src/erasure.d.ts
|
|
2757
|
+
export declare function createStoredRecordErasureHost<TDb>(store: PlatformHostStore<TDb>, authorization: Pick<PlatformHostAuthorization<TDb>, "authorizeStoredRecordErasure">): StoredRecordErasureHost;
|
|
2758
|
+
//#endregion
|
|
2759
|
+
//#region src/erasure-conformance.d.ts
|
|
2760
|
+
export interface ErasureProbeScope {
|
|
2761
|
+
tenantId: string;
|
|
2762
|
+
spaceId: string;
|
|
2763
|
+
invocationId: string;
|
|
2764
|
+
}
|
|
2765
|
+
export interface ErasureSubject<TDb = unknown> {
|
|
2766
|
+
store: PlatformHostStore<TDb> & Partial<ErasablePlatformHostStore<TDb>> & {
|
|
2767
|
+
listEvents?(tenantId: string, spaceId: string): Promise<AssetEventEnvelope[]>;
|
|
2768
|
+
};
|
|
2769
|
+
tenantId: string;
|
|
2770
|
+
/** Test-store fixture access for record kinds not readable through the base store port. */
|
|
2771
|
+
payloadRecords?: {
|
|
2772
|
+
seed(scope: ErasureProbeScope, sentinel: string): Promise<void>;
|
|
2773
|
+
read(scope: ErasureProbeScope): Promise<readonly {
|
|
2774
|
+
kind: ErasureRecordKind;
|
|
2775
|
+
value: unknown;
|
|
2776
|
+
}[]>;
|
|
2777
|
+
};
|
|
2778
|
+
}
|
|
2779
|
+
export interface ErasureCheck {
|
|
2780
|
+
id: string;
|
|
2781
|
+
run(subject: ErasureSubject): Promise<string[]>;
|
|
2782
|
+
}
|
|
2783
|
+
export interface ErasureResult {
|
|
2784
|
+
passed: boolean;
|
|
2785
|
+
checks: Array<{
|
|
2786
|
+
id: string;
|
|
2787
|
+
status: "passed" | "failed" | "skipped";
|
|
2788
|
+
evidence: string[];
|
|
2789
|
+
error?: string;
|
|
2790
|
+
}>;
|
|
2791
|
+
}
|
|
2792
|
+
/** Destructive probes for isolated test stores; leave evidence in fresh probe spaces. */
|
|
2793
|
+
export declare function erasureChecks(): readonly ErasureCheck[];
|
|
2794
|
+
export declare function runErasureChecks<TDb>(subject: ErasureSubject<TDb>): Promise<ErasureResult>;
|
|
2795
|
+
//#endregion
|
|
2796
|
+
//#region src/erasure-errors.d.ts
|
|
2797
|
+
/** Host authorization refusal; contains no target existence or authorizer failure details. */
|
|
2798
|
+
export declare class StoredRecordErasureAuthorizationError extends Error {
|
|
2799
|
+
readonly refusal = "not_authorized";
|
|
2800
|
+
constructor(message: string);
|
|
2801
|
+
}
|
|
2802
|
+
/** A later mutation of an erased record was refused. */
|
|
2803
|
+
export declare class StoredRecordsErasedError extends Error {
|
|
2804
|
+
readonly code = "HOST_RECORDS_ERASED";
|
|
2805
|
+
constructor();
|
|
2806
|
+
}
|
|
2807
|
+
/** Erasure could not lock its targets or finish within the configured budget. */
|
|
2808
|
+
export declare class ErasureBusyError extends Error {
|
|
2809
|
+
readonly reason: "lock_timeout" | "work_timeout";
|
|
2810
|
+
readonly code = "HOST_ERASURE_BUSY";
|
|
2811
|
+
constructor(reason: "lock_timeout" | "work_timeout", options?: ErrorOptions);
|
|
2812
|
+
}
|
|
2813
|
+
//#endregion
|
|
2814
|
+
//#region src/staged-invocation-conformance.d.ts
|
|
2815
|
+
export type StagedContractStore = StagedInvocationPlatformHostStore<unknown> & AtomicMutationPlatformHostStore<unknown>;
|
|
2816
|
+
export interface StagedCreateRotateRaceInput {
|
|
2817
|
+
record: StagedInvocationRecord;
|
|
2818
|
+
workerId: string;
|
|
2819
|
+
leaseToken: number;
|
|
2820
|
+
now: Date;
|
|
2821
|
+
invocation: CreateActionInvocationInput & {
|
|
2822
|
+
stagedOrigin: {
|
|
2823
|
+
parentInvocationId: string;
|
|
2824
|
+
stageKey: string;
|
|
2825
|
+
principal?: string;
|
|
2826
|
+
};
|
|
2827
|
+
};
|
|
2828
|
+
}
|
|
2829
|
+
export interface StagedCreateRotateRaceOutcome {
|
|
2830
|
+
creation: CreateStagedActionInvocationResult;
|
|
2831
|
+
rotatedToken: number | undefined;
|
|
2832
|
+
}
|
|
2833
|
+
/**
|
|
2834
|
+
* A store whose fence can interleave with rotation (PostgreSQL) supplies the
|
|
2835
|
+
* two races with the first operation held open in a transaction, proving the
|
|
2836
|
+
* second waits for it. Without them the contract runs both operations
|
|
2837
|
+
* concurrently, which serializes in the memory store.
|
|
2838
|
+
*/
|
|
2839
|
+
export interface StagedContractHarness {
|
|
2840
|
+
store: StagedContractStore;
|
|
2841
|
+
/** Fenced create held uncommitted; a rotation under the same token must wait for it. */
|
|
2842
|
+
raceCreateThenRotate?(input: StagedCreateRotateRaceInput): Promise<StagedCreateRotateRaceOutcome>;
|
|
2843
|
+
/** Rotation held uncommitted; a fenced create under the old token must wait, then create nothing. */
|
|
2844
|
+
raceRotateThenCreate?(input: StagedCreateRotateRaceInput): Promise<StagedCreateRotateRaceOutcome>;
|
|
2845
|
+
}
|
|
2846
|
+
export interface StagedInvocationSubject {
|
|
2847
|
+
makeHarness(): Promise<StagedContractHarness>;
|
|
2848
|
+
}
|
|
2849
|
+
export interface StagedInvocationCheck {
|
|
2850
|
+
id: string;
|
|
2851
|
+
run(subject: StagedInvocationSubject): Promise<string[]>;
|
|
2852
|
+
}
|
|
2853
|
+
export interface StagedInvocationResult {
|
|
2854
|
+
passed: boolean;
|
|
2855
|
+
checks: Array<{
|
|
2856
|
+
id: string;
|
|
2857
|
+
status: "passed" | "failed" | "skipped";
|
|
2858
|
+
evidence: string[];
|
|
2859
|
+
error?: string;
|
|
2860
|
+
}>;
|
|
2861
|
+
}
|
|
2862
|
+
/** Destructive probes for isolated test stores; leave records in fresh probe spaces. */
|
|
2863
|
+
export declare function stagedInvocationChecks(): readonly StagedInvocationCheck[];
|
|
2864
|
+
export declare function runStagedInvocationChecks(subject: StagedInvocationSubject): Promise<StagedInvocationResult>;
|
|
2865
|
+
//#endregion
|
|
2866
|
+
//#region src/outbox-requeue-conformance.d.ts
|
|
2867
|
+
export interface OutboxRequeueSubject {
|
|
2868
|
+
makeStore(): Promise<OutboxRequeuePlatformHostStore<unknown>>;
|
|
2869
|
+
}
|
|
2870
|
+
export interface OutboxRequeueCheck {
|
|
2871
|
+
id: string;
|
|
2872
|
+
run(subject: OutboxRequeueSubject): Promise<string[]>;
|
|
2873
|
+
}
|
|
2874
|
+
export interface OutboxRequeueResult {
|
|
2875
|
+
passed: boolean;
|
|
2876
|
+
checks: Array<{
|
|
2877
|
+
id: string;
|
|
2878
|
+
status: "passed" | "failed" | "skipped";
|
|
2879
|
+
evidence: string[];
|
|
2880
|
+
error?: string;
|
|
2881
|
+
}>;
|
|
2882
|
+
}
|
|
2883
|
+
/** Destructive probes for isolated test stores; leave outbox and audit records under fresh identities. */
|
|
2884
|
+
export declare function outboxRequeueChecks(): readonly OutboxRequeueCheck[];
|
|
2885
|
+
export declare function runOutboxRequeueChecks(subject: OutboxRequeueSubject): Promise<OutboxRequeueResult>;
|
|
2886
|
+
//#endregion
|
|
2887
|
+
//#region src/approval-conformance.d.ts
|
|
2888
|
+
export type ApprovalCheckStore = ApprovalPlatformHostStore<{}> & Partial<AtomicMutationPlatformHostStore<{}>> & RecoverablePlatformHostStore<{}> & OutboxPlatformHostStore<{}>;
|
|
2889
|
+
export interface ApprovalSubject {
|
|
2890
|
+
makeStore(): Promise<ApprovalCheckStore>;
|
|
2891
|
+
}
|
|
2892
|
+
export interface ApprovalCheck {
|
|
2893
|
+
id: string;
|
|
2894
|
+
run(subject: ApprovalSubject): Promise<string[]>;
|
|
2895
|
+
}
|
|
2896
|
+
export interface ApprovalResult {
|
|
2897
|
+
passed: boolean;
|
|
2898
|
+
checks: Array<{
|
|
2899
|
+
id: string;
|
|
2900
|
+
status: "passed" | "failed" | "skipped";
|
|
2901
|
+
evidence: string[];
|
|
2902
|
+
error?: string;
|
|
2903
|
+
}>;
|
|
2904
|
+
}
|
|
2905
|
+
/** Destructive probes for isolated test stores; leave invocation, event and outbox evidence under fresh identities. */
|
|
2906
|
+
export declare function approvalChecks(): readonly ApprovalCheck[];
|
|
2907
|
+
export declare function runApprovalChecks(subject: ApprovalSubject): Promise<ApprovalResult>;
|
|
2908
|
+
//#endregion
|
|
2909
|
+
//#region src/outbox-relay-conformance.d.ts
|
|
2910
|
+
export interface OutboxRelaySubject {
|
|
2911
|
+
makeStore(): Promise<OutboxPlatformHostStore<unknown>>;
|
|
2912
|
+
}
|
|
2913
|
+
export interface OutboxRelayCheck {
|
|
2914
|
+
id: string;
|
|
2915
|
+
run(subject: OutboxRelaySubject): Promise<string[]>;
|
|
2916
|
+
}
|
|
2917
|
+
export interface OutboxRelayConformanceResult {
|
|
2918
|
+
passed: boolean;
|
|
2919
|
+
checks: Array<{
|
|
2920
|
+
id: string;
|
|
2921
|
+
status: "passed" | "failed" | "skipped";
|
|
2922
|
+
evidence: string[];
|
|
2923
|
+
error?: string;
|
|
2924
|
+
}>;
|
|
2925
|
+
}
|
|
2926
|
+
/** Destructive probes for isolated test stores; leave outbox records under fresh identities and spaces. */
|
|
2927
|
+
export declare function outboxRelayChecks(): readonly OutboxRelayCheck[];
|
|
2928
|
+
export declare function runOutboxRelayChecks(subject: OutboxRelaySubject): Promise<OutboxRelayConformanceResult>;
|
|
2929
|
+
//#endregion
|
|
2930
|
+
//#region src/invocation-idempotency-conformance.d.ts
|
|
2931
|
+
export interface InvocationIdempotencySubject {
|
|
2932
|
+
makeStore(): Promise<PlatformHostStore<unknown>>;
|
|
2933
|
+
}
|
|
2934
|
+
export interface InvocationIdempotencyCheck {
|
|
2935
|
+
id: string;
|
|
2936
|
+
run(subject: InvocationIdempotencySubject): Promise<string[]>;
|
|
2937
|
+
}
|
|
2938
|
+
export interface InvocationIdempotencyResult {
|
|
2939
|
+
passed: boolean;
|
|
2940
|
+
checks: Array<{
|
|
2941
|
+
id: string;
|
|
2942
|
+
status: "passed" | "failed" | "skipped";
|
|
2943
|
+
evidence: string[];
|
|
2944
|
+
error?: string;
|
|
2945
|
+
}>;
|
|
2946
|
+
}
|
|
2947
|
+
/** Destructive probes for isolated test stores; leave invocation records under fresh identities and spaces. */
|
|
2948
|
+
export declare function invocationIdempotencyChecks(): readonly InvocationIdempotencyCheck[];
|
|
2949
|
+
export declare function runInvocationIdempotencyChecks(subject: InvocationIdempotencySubject): Promise<InvocationIdempotencyResult>;
|
|
2950
|
+
//#endregion
|
|
2951
|
+
//#region src/transaction-rollback.d.ts
|
|
2952
|
+
/** Evidence from a transaction provider that rollback completed successfully. */
|
|
2953
|
+
export declare class ConfirmedTransactionRollback extends Error {
|
|
2954
|
+
readonly name = "ConfirmedTransactionRollback";
|
|
2955
|
+
readonly code: "TRANSACTION_ROLLBACK_CONFIRMED";
|
|
2956
|
+
constructor(cause: unknown);
|
|
2957
|
+
}
|
|
2958
|
+
/** Recognise rollback evidence across ESM/CommonJS or other package copies. */
|
|
2959
|
+
export declare function isConfirmedTransactionRollback(error: unknown): error is ConfirmedTransactionRollback;
|
|
2960
|
+
/** Inspect up to 16 errors, failing closed on cycles or unreadable properties. Intended for handlerRetry.classify. */
|
|
2961
|
+
export declare function isTransientPostgresTransactionError(error: unknown): boolean;
|
|
2962
|
+
//#endregion
|
|
2963
|
+
//#region src/submission-outcome.d.ts
|
|
2964
|
+
export declare class SubmissionOutcomeUnsupportedError extends Error {
|
|
2965
|
+
constructor();
|
|
2966
|
+
}
|
|
2967
|
+
//#endregion
|
|
2968
|
+
//#region src/submission-outcome-conformance.d.ts
|
|
2969
|
+
/**
|
|
2970
|
+
* Isolated destructive probe with fresh identities and timestamps from new Date().
|
|
2971
|
+
* Refusal and erasure sections run only with their respective store capabilities;
|
|
2972
|
+
* returned evidence identifies each unexercised optional section with `skipped:`.
|
|
2973
|
+
*/
|
|
2974
|
+
export declare function checkSubmissionOutcomeStore(store: PlatformHostStore<unknown>): Promise<string[]>;
|
|
2975
|
+
//#endregion
|
|
2976
|
+
export { type ErasablePlatformHostStore, type EraseStoredRecordsInput, type EraseStoredRecordsResult, type ErasurePayloadFields, type ErasureRecordKind, type StoredRecordErasureAuthorizationInput, type StoredRecordErasureHost, type StoredRecordErasureOutcome, type StoredRecordErasureTarget, type StoredRecordErasureView, canonicalJson };
|