@fabricorg/platform-host 8.2.0 → 8.4.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 +39 -0
- package/README.md +136 -4
- package/dist/index.cjs +1196 -23
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +357 -14
- package/dist/index.d.ts +357 -14
- package/dist/index.js +1188 -25
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ActionDefinition, ActionId, ActionStatus, ActorType, AdapterCircuitBreakerProvider, AdapterImplementation, AgentActionPolicyEvaluator, AgentActionRiskTier, AgentActionRoute, AssetEventEnvelope, EvidencePacketReference, ExecutionAttestation, ExecutionPrincipal, ExternalReconciliation, FabricRuntimeServices, GovernanceRuntimeEvidence, ModuleRegistry, MutationFootprint, MutationGovernanceResolver, PolicyObligation, PolicyObligationStatus, PolicyOutcome, RuntimePolicyDefinition, canonicalJson } from "@fabricorg/platform";
|
|
1
|
+
import { ActionDefinition, ActionId, ActionStatus, ActorType, AdapterCircuitBreakerProvider, AdapterImplementation, AgentActionPolicyEvaluator, 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
3
|
//#region src/observability.d.ts
|
|
4
4
|
/** Version of the vendor-neutral health/readiness contract. */
|
|
@@ -218,6 +218,14 @@ export declare class ActionAdmissionError extends Error {
|
|
|
218
218
|
/** The check's own code, present only for `refused`. */
|
|
219
219
|
refusalCode?: string | undefined);
|
|
220
220
|
}
|
|
221
|
+
export type SubmissionRefusal = "entitlement" | "authorization";
|
|
222
|
+
/** A definitive authorization-boundary refusal before an invocation is created. */
|
|
223
|
+
export declare class SubmissionRefusalError extends Error {
|
|
224
|
+
readonly actionId: string;
|
|
225
|
+
readonly refusal: SubmissionRefusal;
|
|
226
|
+
readonly code: "ACTION_SUBMISSION_REFUSED";
|
|
227
|
+
constructor(actionId: string, refusal: SubmissionRefusal, message: string);
|
|
228
|
+
}
|
|
221
229
|
export type ExternalCompletionRefusal = "still_executing" | "not_found" | "not_awaiting" | "immediate_contract" | "reference_mismatch" | "provider_mismatch" | "invalid_completion" | "result_invalid" | "redaction_failed";
|
|
222
230
|
/**
|
|
223
231
|
* Why a completion was not applied, typed so a webhook handler can answer
|
|
@@ -259,6 +267,12 @@ export interface FinalizationCheckpoint {
|
|
|
259
267
|
payload: import("@fabricorg/platform").FinalizationJson;
|
|
260
268
|
};
|
|
261
269
|
skipped: number[];
|
|
270
|
+
/** Handler requests retained so finalization replay stages the identical batch. */
|
|
271
|
+
stagedInvocations?: readonly import("@fabricorg/platform").StagedInvocationRequest[];
|
|
272
|
+
}
|
|
273
|
+
export interface StagedInvocationOrigin {
|
|
274
|
+
parentInvocationId: string;
|
|
275
|
+
stageKey: string;
|
|
262
276
|
}
|
|
263
277
|
export interface ActionInvocationRecord {
|
|
264
278
|
id: string;
|
|
@@ -278,6 +292,8 @@ export interface ActionInvocationRecord {
|
|
|
278
292
|
parameterDigestAlgorithm?: "fabric-canonical-json-sha256-v1";
|
|
279
293
|
idempotencyActorId?: string;
|
|
280
294
|
idempotencyAuthorizationBindingId?: string;
|
|
295
|
+
/** Host-only identity for a staged child; public submissions cannot set it. */
|
|
296
|
+
stagedOrigin?: StagedInvocationOrigin;
|
|
281
297
|
provenance?: Omit<InvocationProvenance, "traceAttributes">;
|
|
282
298
|
authorizationBinding?: AuthorizationBinding;
|
|
283
299
|
executionReason?: ActionExecutionReason;
|
|
@@ -479,7 +495,7 @@ export interface AdapterInvocationRecord {
|
|
|
479
495
|
createdAt: Date;
|
|
480
496
|
updatedAt: Date;
|
|
481
497
|
}
|
|
482
|
-
export interface CreateActionInvocationInput extends Omit<ActionInvocationRecord, "createdAt" | "updatedAt" | "attemptCount" | "leaseOwner" | "leaseExpiresAt" | "leaseToken"> {}
|
|
498
|
+
export interface CreateActionInvocationInput extends Omit<ActionInvocationRecord, "createdAt" | "updatedAt" | "attemptCount" | "leaseOwner" | "leaseExpiresAt" | "leaseToken" | "stagedOrigin"> {}
|
|
483
499
|
/** Scope of an adapter checkpoint within its owning action invocation. */
|
|
484
500
|
export interface AdapterInvocationScope {
|
|
485
501
|
tenantId: string;
|
|
@@ -537,6 +553,8 @@ export interface PlatformHostStore<TDb> {
|
|
|
537
553
|
transaction<TResult>(run: (db: TDb) => Promise<TResult>): Promise<TResult>;
|
|
538
554
|
createActionInvocation(input: CreateActionInvocationInput): Promise<ActionInvocationRecord>;
|
|
539
555
|
getActionInvocation(id: string, tenantId: string, spaceId: string): Promise<ActionInvocationRecord | undefined>;
|
|
556
|
+
/** Resolve Host-owned staged identity within one tenant and space. */
|
|
557
|
+
getActionInvocationByStagedOrigin?(tenantId: string, spaceId: string, origin: StagedInvocationOrigin): Promise<ActionInvocationRecord | undefined>;
|
|
540
558
|
updateActionInvocation(id: string, tenantId: string, spaceId: string, patch: ActionInvocationPatch): Promise<void>;
|
|
541
559
|
appendPolicyEvaluation(record: PolicyEvaluationRecord): Promise<void>;
|
|
542
560
|
createAdapterInvocation(record: AdapterInvocationRecord): Promise<void>;
|
|
@@ -668,6 +686,135 @@ export interface PlatformHostMutationTransaction<TDb> {
|
|
|
668
686
|
* governance evidence cannot share the event/verdict transaction.
|
|
669
687
|
*/
|
|
670
688
|
appendExternalReconciliation?: GovernancePlatformHostStore<TDb>["appendExternalReconciliation"];
|
|
689
|
+
/** Atomically retain an immutable staged batch with the parent mutation. */
|
|
690
|
+
stageInvocations?(records: readonly StagedInvocationRecord[]): Promise<void>;
|
|
691
|
+
}
|
|
692
|
+
export type StagedInvocationStatus = "pending" | "dispatched" | "rejected" | "dead_lettered" | "cancelled";
|
|
693
|
+
export interface StagedInvocationRecord {
|
|
694
|
+
id: string;
|
|
695
|
+
tenantId: string;
|
|
696
|
+
spaceId: string;
|
|
697
|
+
parentInvocationId: string;
|
|
698
|
+
parentActionId: ActionId;
|
|
699
|
+
key: string;
|
|
700
|
+
actionId: ActionId;
|
|
701
|
+
expectedActionVersion: number;
|
|
702
|
+
parameters: Record<string, unknown>;
|
|
703
|
+
parameterDigest: string;
|
|
704
|
+
batchDigest: string;
|
|
705
|
+
status: StagedInvocationStatus;
|
|
706
|
+
/**
|
|
707
|
+
* The child's id, recorded by the first settlement whose attempt knew it.
|
|
708
|
+
* A settlement without an id leaves an earlier one in place. After a crash
|
|
709
|
+
* between child creation and settlement it stays absent until a later
|
|
710
|
+
* attempt finds the child by its staged origin.
|
|
711
|
+
*/
|
|
712
|
+
childInvocationId?: string;
|
|
713
|
+
attemptCount: number;
|
|
714
|
+
availableAt: Date;
|
|
715
|
+
leaseOwner?: string;
|
|
716
|
+
leaseExpiresAt?: Date;
|
|
717
|
+
leaseToken: number;
|
|
718
|
+
lastError?: string;
|
|
719
|
+
createdAt: Date;
|
|
720
|
+
updatedAt: Date;
|
|
721
|
+
}
|
|
722
|
+
export interface ClaimStagedInvocationsInput {
|
|
723
|
+
workerId: string;
|
|
724
|
+
leaseDurationMs: number;
|
|
725
|
+
limit?: number;
|
|
726
|
+
tenantId?: string;
|
|
727
|
+
spaceId?: string;
|
|
728
|
+
now?: Date;
|
|
729
|
+
}
|
|
730
|
+
export interface CreateStagedActionInvocationInput {
|
|
731
|
+
stageId: string;
|
|
732
|
+
workerId: string;
|
|
733
|
+
leaseToken: number;
|
|
734
|
+
now?: Date;
|
|
735
|
+
invocation: CreateActionInvocationInput & {
|
|
736
|
+
stagedOrigin: StagedInvocationOrigin;
|
|
737
|
+
};
|
|
738
|
+
}
|
|
739
|
+
export type CreateStagedActionInvocationResult = {
|
|
740
|
+
kind: "created" | "existing";
|
|
741
|
+
invocation: ActionInvocationRecord;
|
|
742
|
+
} | {
|
|
743
|
+
kind: "lease_lost";
|
|
744
|
+
};
|
|
745
|
+
/** Optional durable capability for transactional staging and post-completion dispatch. */
|
|
746
|
+
export interface StagedInvocationPlatformHostStore<TDb> extends PlatformHostStore<TDb> {
|
|
747
|
+
readonly transactionalStagedInvocations?: boolean;
|
|
748
|
+
getActionInvocationByStagedOrigin(tenantId: string, spaceId: string, origin: StagedInvocationOrigin): Promise<ActionInvocationRecord | undefined>;
|
|
749
|
+
/** Return the existing origin or create it only while this exact stage lease is live. */
|
|
750
|
+
createActionInvocationForStagedLease(input: CreateStagedActionInvocationInput): Promise<CreateStagedActionInvocationResult>;
|
|
751
|
+
claimStagedInvocations(input: ClaimStagedInvocationsInput): Promise<StagedInvocationRecord[]>;
|
|
752
|
+
/**
|
|
753
|
+
* The settlements below are each one compare-and-set on a pending row's
|
|
754
|
+
* lease owner and token, and release the lease. A settlement that carries
|
|
755
|
+
* `childInvocationId` records it; one without leaves a recorded id in place.
|
|
756
|
+
*/
|
|
757
|
+
markStagedInvocationDispatched(input: {
|
|
758
|
+
id: string;
|
|
759
|
+
workerId: string;
|
|
760
|
+
leaseToken: number;
|
|
761
|
+
childInvocationId: string;
|
|
762
|
+
now?: Date;
|
|
763
|
+
}): Promise<boolean>;
|
|
764
|
+
markStagedInvocationRejected(input: {
|
|
765
|
+
id: string;
|
|
766
|
+
workerId: string;
|
|
767
|
+
leaseToken: number;
|
|
768
|
+
error: string;
|
|
769
|
+
now?: Date;
|
|
770
|
+
}): Promise<boolean>;
|
|
771
|
+
markStagedInvocationFailed(input: {
|
|
772
|
+
id: string;
|
|
773
|
+
workerId: string;
|
|
774
|
+
leaseToken: number;
|
|
775
|
+
error: string;
|
|
776
|
+
availableAt: Date;
|
|
777
|
+
deadLetter: boolean;
|
|
778
|
+
childInvocationId?: string;
|
|
779
|
+
now?: Date;
|
|
780
|
+
}): Promise<boolean>;
|
|
781
|
+
renewStagedInvocationLease(input: {
|
|
782
|
+
id: string;
|
|
783
|
+
workerId: string;
|
|
784
|
+
leaseToken: number;
|
|
785
|
+
leaseDurationMs: number;
|
|
786
|
+
now?: Date;
|
|
787
|
+
}): Promise<boolean>;
|
|
788
|
+
/**
|
|
789
|
+
* Replace the lease token of a pending row this worker leases with a larger
|
|
790
|
+
* one and extend the lease, in one compare-and-set on owner, token and an
|
|
791
|
+
* unexpired lease. Returns the new token, or `undefined` when the lease no
|
|
792
|
+
* longer matches. Tokens only grow, as with claims, so a later claim never
|
|
793
|
+
* hands an old token out again. Afterwards the old token fails the
|
|
794
|
+
* child-creation fence, renewal and every settlement. A store must order
|
|
795
|
+
* the rotation after any child creation the fence already admitted under
|
|
796
|
+
* the old token (PostgreSQL: the fence's `FOR SHARE` row lock makes the
|
|
797
|
+
* rotation wait). Host rotates before the lookup that decides a stage
|
|
798
|
+
* whose attempt holds no child id.
|
|
799
|
+
*/
|
|
800
|
+
rotateStagedInvocationLease(input: {
|
|
801
|
+
id: string;
|
|
802
|
+
workerId: string;
|
|
803
|
+
leaseToken: number;
|
|
804
|
+
leaseDurationMs: number;
|
|
805
|
+
now?: Date;
|
|
806
|
+
}): Promise<number | undefined>;
|
|
807
|
+
cancelStagedInvocationsForFailedParents(input?: {
|
|
808
|
+
tenantId?: string;
|
|
809
|
+
spaceId?: string;
|
|
810
|
+
now?: Date;
|
|
811
|
+
}): Promise<number>;
|
|
812
|
+
listStagedInvocations(input: {
|
|
813
|
+
tenantId: string;
|
|
814
|
+
spaceId: string;
|
|
815
|
+
parentInvocationId?: string;
|
|
816
|
+
statuses?: readonly StagedInvocationStatus[];
|
|
817
|
+
}): Promise<StagedInvocationRecord[]>;
|
|
671
818
|
}
|
|
672
819
|
export type OutboxStatus = "pending" | "published" | "dead_letter";
|
|
673
820
|
export type EventPayloadClassification = "public" | "internal" | "confidential" | "restricted";
|
|
@@ -1013,7 +1160,7 @@ export interface ActionAuthorizationInput {
|
|
|
1013
1160
|
actorId: string;
|
|
1014
1161
|
actorType: ActorType;
|
|
1015
1162
|
}
|
|
1016
|
-
export type KnownActionExecutionReason = "initial" | "approval_resume" | "recovery" | "offline_replay";
|
|
1163
|
+
export type KnownActionExecutionReason = "initial" | "approval_resume" | "recovery" | "offline_replay" | "staged_dispatch";
|
|
1017
1164
|
export type ActionExecutionReason = KnownActionExecutionReason | (string & {});
|
|
1018
1165
|
/**
|
|
1019
1166
|
* Trusted execution-boundary authorization input.
|
|
@@ -1027,6 +1174,14 @@ export interface ActionExecutionAuthorizationInput extends ActionAuthorizationIn
|
|
|
1027
1174
|
invocation: Readonly<ActionInvocationRecord>;
|
|
1028
1175
|
executionReason: ActionExecutionReason;
|
|
1029
1176
|
}
|
|
1177
|
+
/** Trusted authorization input for deciding a parked approval. */
|
|
1178
|
+
export interface ActionApprovalAuthorizationInput extends ActionAuthorizationInput {
|
|
1179
|
+
decision: ActionApprovalDecision;
|
|
1180
|
+
/** The parked invocation being decided. */
|
|
1181
|
+
actionInvocationId: string;
|
|
1182
|
+
/** The durable (post-redaction) invocation record as read before the decision transition. */
|
|
1183
|
+
invocation: Readonly<ActionInvocationRecord>;
|
|
1184
|
+
}
|
|
1030
1185
|
/**
|
|
1031
1186
|
* Input to `resolvePolicies`. Carries the invocation identity and the
|
|
1032
1187
|
* schema-parsed durable (post-redaction) parameters so a resolver can choose
|
|
@@ -1046,9 +1201,7 @@ export interface PlatformHostAuthorization {
|
|
|
1046
1201
|
*/
|
|
1047
1202
|
authorizeExecution?(input: ActionExecutionAuthorizationInput): Promise<boolean>;
|
|
1048
1203
|
/** Optional distinct authorization boundary for human/system approval decisions. */
|
|
1049
|
-
authorizeApproval?(input:
|
|
1050
|
-
decision: ActionApprovalDecision;
|
|
1051
|
-
}): Promise<boolean>;
|
|
1204
|
+
authorizeApproval?(input: ActionApprovalAuthorizationInput): Promise<boolean>;
|
|
1052
1205
|
/**
|
|
1053
1206
|
* Authorization for `requeueOutboxDeadLetter`. There is no action to fall
|
|
1054
1207
|
* back to, so when this is absent every requeue is refused as
|
|
@@ -1154,6 +1307,14 @@ export interface PlatformActionWorkerOptions<TDb> {
|
|
|
1154
1307
|
* on every cycle, and run the sweep elsewhere.
|
|
1155
1308
|
*/
|
|
1156
1309
|
sweepOverdueCompletions?: boolean;
|
|
1310
|
+
/** Dispatch staged descendants each cycle. Defaults to on when a registered action declares them. */
|
|
1311
|
+
dispatchStagedInvocations?: boolean;
|
|
1312
|
+
stagedInvocationBatchSize?: number;
|
|
1313
|
+
stagedInvocationLeaseDurationMs?: number;
|
|
1314
|
+
stagedInvocationLeaseRenewalIntervalMs?: number;
|
|
1315
|
+
stagedInvocationSubmissionTimeoutMs?: number;
|
|
1316
|
+
stagedInvocationMaxAttempts?: number;
|
|
1317
|
+
stagedInvocationRetryDelayMs?: (attempt: number) => number;
|
|
1157
1318
|
}
|
|
1158
1319
|
export interface PlatformActionWorkerCycleResult {
|
|
1159
1320
|
claimed: number;
|
|
@@ -1167,6 +1328,38 @@ export interface PlatformActionWorkerCycleResult {
|
|
|
1167
1328
|
* The row stays leased and a later claim retries it; excluded from failed.
|
|
1168
1329
|
*/
|
|
1169
1330
|
deferred?: number;
|
|
1331
|
+
staged?: StagedInvocationDispatchResult;
|
|
1332
|
+
}
|
|
1333
|
+
export interface StagedInvocationDispatchInput {
|
|
1334
|
+
workerId: string;
|
|
1335
|
+
limit?: number;
|
|
1336
|
+
leaseDurationMs?: number;
|
|
1337
|
+
leaseRenewalIntervalMs?: number;
|
|
1338
|
+
submissionTimeoutMs?: number;
|
|
1339
|
+
maxAttempts?: number;
|
|
1340
|
+
retryDelayMs?: (attempt: number) => number;
|
|
1341
|
+
tenantId?: string;
|
|
1342
|
+
spaceId?: string;
|
|
1343
|
+
/**
|
|
1344
|
+
* Receives a failed staged-origin lookup and any error that ends one claimed
|
|
1345
|
+
* row's processing early (a store error from renewal, rotation or
|
|
1346
|
+
* settlement). The sweep counts that row as failed and continues.
|
|
1347
|
+
*/
|
|
1348
|
+
onError?: (error: unknown) => void;
|
|
1349
|
+
}
|
|
1350
|
+
/**
|
|
1351
|
+
* Counters for one sweep. Each claimed row is counted once, as dispatched,
|
|
1352
|
+
* rejected or failed. `failed` includes rows settled for retry, rows whose
|
|
1353
|
+
* lease was lost before settlement, and rows whose processing threw;
|
|
1354
|
+
* `deadLettered` counts the subset of `failed` settled as `dead_lettered`.
|
|
1355
|
+
*/
|
|
1356
|
+
export interface StagedInvocationDispatchResult {
|
|
1357
|
+
claimed: number;
|
|
1358
|
+
dispatched: number;
|
|
1359
|
+
rejected: number;
|
|
1360
|
+
failed: number;
|
|
1361
|
+
deadLettered: number;
|
|
1362
|
+
cancelled: number;
|
|
1170
1363
|
}
|
|
1171
1364
|
/** Origin of error text redacted before Host records or returns it. */
|
|
1172
1365
|
export interface ErrorTextRedactionContext {
|
|
@@ -1369,6 +1562,10 @@ export interface PlatformHostOptions<TDb> {
|
|
|
1369
1562
|
}
|
|
1370
1563
|
export interface GovernedActionHost {
|
|
1371
1564
|
submitAction(input: SubmitActionInput): Promise<SubmitActionResult>;
|
|
1565
|
+
/** Whether this Host's registry contains an action with a non-empty staged-descendant allowlist. */
|
|
1566
|
+
readonly hasStagedInvocationActions?: boolean;
|
|
1567
|
+
/** One bounded lease-fenced sweep of completed parents' staged descendants. */
|
|
1568
|
+
dispatchStagedInvocations?(input: StagedInvocationDispatchInput): Promise<StagedInvocationDispatchResult>;
|
|
1372
1569
|
executeInvocation(actionInvocationId: string, tenantId: string, spaceId: string, options?: ExecuteInvocationOptions): Promise<ExecuteActionResult>;
|
|
1373
1570
|
resumeApprovedInvocation(actionInvocationId: string, tenantId: string, spaceId: string, decision: ActionApprovalDecision): Promise<ExecuteActionResult>;
|
|
1374
1571
|
recordExecutionAttestation(actionInvocationId: string, tenantId: string, spaceId: string, attestation: ExecutionAttestation): Promise<void>;
|
|
@@ -1415,9 +1612,10 @@ export interface MemoryPlatformHostTransactionProvider<TDb> {
|
|
|
1415
1612
|
snapshot(db: TDb): TDb;
|
|
1416
1613
|
restore(db: TDb, snapshot: TDb): void;
|
|
1417
1614
|
}
|
|
1418
|
-
export declare class MemoryPlatformHostStore<TDb> implements RecoverablePlatformHostStore<TDb>, ApprovalPlatformHostStore<TDb>, GovernancePlatformHostStore<TDb>, OutboxPlatformHostStore<TDb>, OutboxRequeuePlatformHostStore<TDb> {
|
|
1615
|
+
export declare class MemoryPlatformHostStore<TDb> implements RecoverablePlatformHostStore<TDb>, ApprovalPlatformHostStore<TDb>, GovernancePlatformHostStore<TDb>, OutboxPlatformHostStore<TDb>, OutboxRequeuePlatformHostStore<TDb>, StagedInvocationPlatformHostStore<TDb> {
|
|
1419
1616
|
readonly db: TDb;
|
|
1420
1617
|
readonly transactionalOutbox: boolean;
|
|
1618
|
+
readonly transactionalStagedInvocations: boolean;
|
|
1421
1619
|
transactionWithEvents?: <TResult>(run: (transaction: PlatformHostMutationTransaction<TDb>) => Promise<TResult>) => Promise<TResult>;
|
|
1422
1620
|
private adapterCommit;
|
|
1423
1621
|
private transactionTail;
|
|
@@ -1429,6 +1627,7 @@ export declare class MemoryPlatformHostStore<TDb> implements RecoverablePlatform
|
|
|
1429
1627
|
readonly executionAttestations: ExecutionAttestationRecord[];
|
|
1430
1628
|
readonly externalReconciliations: ExternalReconciliationRecord[];
|
|
1431
1629
|
readonly outbox: OutboxRecord[];
|
|
1630
|
+
readonly stagedInvocations: StagedInvocationRecord[];
|
|
1432
1631
|
/**
|
|
1433
1632
|
* Requeue evidence is append-only audit history, so unlike the ledger
|
|
1434
1633
|
* arrays above, which tests have always inspected and seeded directly, it
|
|
@@ -1440,7 +1639,10 @@ export declare class MemoryPlatformHostStore<TDb> implements RecoverablePlatform
|
|
|
1440
1639
|
transaction<TResult>(run: (db: TDb) => Promise<TResult>): Promise<TResult>;
|
|
1441
1640
|
private runTransactionWithEvents;
|
|
1442
1641
|
createActionInvocation(input: CreateActionInvocationInput): Promise<ActionInvocationRecord>;
|
|
1642
|
+
createActionInvocationForStagedLease(input: CreateStagedActionInvocationInput): Promise<CreateStagedActionInvocationResult>;
|
|
1643
|
+
private applyStagedBatch;
|
|
1443
1644
|
getActionInvocation(id: string, tenantId: string, spaceId: string): Promise<ActionInvocationRecord | undefined>;
|
|
1645
|
+
getActionInvocationByStagedOrigin(tenantId: string, spaceId: string, origin: StagedInvocationOrigin): Promise<ActionInvocationRecord | undefined>;
|
|
1444
1646
|
updateActionInvocation(id: string, tenantId: string, spaceId: string, patch: ActionInvocationPatch): Promise<void>;
|
|
1445
1647
|
recordHitlDecision(actionInvocationId: string, tenantId: string, spaceId: string, decision: HitlDecisionEvidence): Promise<ActionInvocationRecord>;
|
|
1446
1648
|
beginApprovalDecision(input: BeginApprovalDecisionInput): Promise<ApprovalDecisionTransitionResult>;
|
|
@@ -1504,6 +1706,60 @@ export declare class MemoryPlatformHostStore<TDb> implements RecoverablePlatform
|
|
|
1504
1706
|
claimActionInvocations(input: ClaimActionInvocationsInput): Promise<ActionInvocationRecord[]>;
|
|
1505
1707
|
updateLeasedActionInvocation(input: UpdateLeasedActionInvocationInput): Promise<boolean>;
|
|
1506
1708
|
renewActionInvocationLease(input: RenewActionInvocationLeaseInput): Promise<boolean>;
|
|
1709
|
+
claimStagedInvocations(input: ClaimStagedInvocationsInput): Promise<StagedInvocationRecord[]>;
|
|
1710
|
+
markStagedInvocationDispatched(input: {
|
|
1711
|
+
id: string;
|
|
1712
|
+
workerId: string;
|
|
1713
|
+
leaseToken: number;
|
|
1714
|
+
childInvocationId: string;
|
|
1715
|
+
now?: Date;
|
|
1716
|
+
}): Promise<boolean>;
|
|
1717
|
+
markStagedInvocationRejected(input: {
|
|
1718
|
+
id: string;
|
|
1719
|
+
workerId: string;
|
|
1720
|
+
leaseToken: number;
|
|
1721
|
+
error: string;
|
|
1722
|
+
now?: Date;
|
|
1723
|
+
}): Promise<boolean>;
|
|
1724
|
+
markStagedInvocationFailed(input: {
|
|
1725
|
+
id: string;
|
|
1726
|
+
workerId: string;
|
|
1727
|
+
leaseToken: number;
|
|
1728
|
+
error: string;
|
|
1729
|
+
availableAt: Date;
|
|
1730
|
+
deadLetter: boolean;
|
|
1731
|
+
childInvocationId?: string;
|
|
1732
|
+
now?: Date;
|
|
1733
|
+
}): Promise<boolean>;
|
|
1734
|
+
renewStagedInvocationLease(input: {
|
|
1735
|
+
id: string;
|
|
1736
|
+
workerId: string;
|
|
1737
|
+
leaseToken: number;
|
|
1738
|
+
leaseDurationMs: number;
|
|
1739
|
+
now?: Date;
|
|
1740
|
+
}): Promise<boolean>;
|
|
1741
|
+
/** Await-free, like the fenced create above, so a create runs wholly before or after it. */
|
|
1742
|
+
rotateStagedInvocationLease(input: {
|
|
1743
|
+
id: string;
|
|
1744
|
+
workerId: string;
|
|
1745
|
+
leaseToken: number;
|
|
1746
|
+
leaseDurationMs: number;
|
|
1747
|
+
now?: Date;
|
|
1748
|
+
}): Promise<number | undefined>;
|
|
1749
|
+
cancelStagedInvocationsForFailedParents(input?: {
|
|
1750
|
+
tenantId?: string;
|
|
1751
|
+
spaceId?: string;
|
|
1752
|
+
now?: Date;
|
|
1753
|
+
}): Promise<number>;
|
|
1754
|
+
listStagedInvocations(input: {
|
|
1755
|
+
tenantId: string;
|
|
1756
|
+
spaceId: string;
|
|
1757
|
+
parentInvocationId?: string;
|
|
1758
|
+
statuses?: readonly StagedInvocationStatus[];
|
|
1759
|
+
}): Promise<StagedInvocationRecord[]>;
|
|
1760
|
+
private leasedStagedInvocation;
|
|
1761
|
+
/** Mirrors PostgreSQL: a missing child id keeps the recorded one; `lastError` is replaced. */
|
|
1762
|
+
private settleStagedInvocation;
|
|
1507
1763
|
listEvents(tenantId: string, spaceId: string): Promise<AssetEventEnvelope[]>;
|
|
1508
1764
|
}
|
|
1509
1765
|
//#endregion
|
|
@@ -1571,16 +1827,20 @@ export interface PostgresPlatformHostTransactionProvider<TDb> {
|
|
|
1571
1827
|
run<TResult>(run: (context: PostgresPlatformHostTransactionContext<TDb>) => Promise<TResult>): Promise<TResult>;
|
|
1572
1828
|
}
|
|
1573
1829
|
/** Durable mutation-pipeline ledger for Databricks Lakebase or standard Postgres. */
|
|
1574
|
-
export declare class PostgresPlatformHostStore<TDb> implements RecoverablePlatformHostStore<TDb>, ApprovalPlatformHostStore<TDb>, GovernancePlatformHostStore<TDb>, OutboxPlatformHostStore<TDb>, OutboxRequeuePlatformHostStore<TDb> {
|
|
1830
|
+
export declare class PostgresPlatformHostStore<TDb> implements RecoverablePlatformHostStore<TDb>, ApprovalPlatformHostStore<TDb>, GovernancePlatformHostStore<TDb>, OutboxPlatformHostStore<TDb>, OutboxRequeuePlatformHostStore<TDb>, StagedInvocationPlatformHostStore<TDb> {
|
|
1575
1831
|
readonly db: TDb;
|
|
1576
1832
|
private readonly sql;
|
|
1577
1833
|
readonly transactionWithEvents?: AtomicMutationPlatformHostStore<TDb>["transactionWithEvents"];
|
|
1578
1834
|
readonly transactionalOutbox: boolean;
|
|
1835
|
+
readonly transactionalStagedInvocations: boolean;
|
|
1579
1836
|
constructor(db: TDb, sql: PlatformHostSqlClient, transactionProvider?: PostgresPlatformHostTransactionProvider<TDb>);
|
|
1580
1837
|
ensureSchema(): Promise<void>;
|
|
1581
1838
|
transaction<TResult>(run: (db: TDb) => Promise<TResult>): Promise<TResult>;
|
|
1582
1839
|
createActionInvocation(input: CreateActionInvocationInput): Promise<ActionInvocationRecord>;
|
|
1840
|
+
createActionInvocationForStagedLease(input: CreateStagedActionInvocationInput): Promise<CreateStagedActionInvocationResult>;
|
|
1841
|
+
stageInvocations(records: readonly StagedInvocationRecord[]): Promise<void>;
|
|
1583
1842
|
getActionInvocation(id: string, tenantId: string, spaceId: string): Promise<ActionInvocationRecord | undefined>;
|
|
1843
|
+
getActionInvocationByStagedOrigin(tenantId: string, spaceId: string, origin: StagedInvocationOrigin): Promise<ActionInvocationRecord | undefined>;
|
|
1584
1844
|
updateActionInvocation(id: string, tenantId: string, spaceId: string, patch: ActionInvocationPatch): Promise<void>;
|
|
1585
1845
|
recordHitlDecision(actionInvocationId: string, tenantId: string, spaceId: string, decision: HitlDecisionEvidence): Promise<ActionInvocationRecord>;
|
|
1586
1846
|
beginApprovalDecision(input: BeginApprovalDecisionInput): Promise<ApprovalDecisionTransitionResult>;
|
|
@@ -1631,6 +1891,66 @@ export declare class PostgresPlatformHostStore<TDb> implements RecoverablePlatfo
|
|
|
1631
1891
|
spaceId: string;
|
|
1632
1892
|
outboxId?: string;
|
|
1633
1893
|
}): Promise<OutboxRequeueRecord[]>;
|
|
1894
|
+
claimStagedInvocations(input: ClaimStagedInvocationsInput): Promise<StagedInvocationRecord[]>;
|
|
1895
|
+
markStagedInvocationDispatched(input: {
|
|
1896
|
+
id: string;
|
|
1897
|
+
workerId: string;
|
|
1898
|
+
leaseToken: number;
|
|
1899
|
+
childInvocationId: string;
|
|
1900
|
+
now?: Date;
|
|
1901
|
+
}): Promise<boolean>;
|
|
1902
|
+
markStagedInvocationRejected(input: {
|
|
1903
|
+
id: string;
|
|
1904
|
+
workerId: string;
|
|
1905
|
+
leaseToken: number;
|
|
1906
|
+
error: string;
|
|
1907
|
+
now?: Date;
|
|
1908
|
+
}): Promise<boolean>;
|
|
1909
|
+
markStagedInvocationFailed(input: {
|
|
1910
|
+
id: string;
|
|
1911
|
+
workerId: string;
|
|
1912
|
+
leaseToken: number;
|
|
1913
|
+
error: string;
|
|
1914
|
+
availableAt: Date;
|
|
1915
|
+
deadLetter: boolean;
|
|
1916
|
+
childInvocationId?: string;
|
|
1917
|
+
now?: Date;
|
|
1918
|
+
}): Promise<boolean>;
|
|
1919
|
+
renewStagedInvocationLease(input: {
|
|
1920
|
+
id: string;
|
|
1921
|
+
workerId: string;
|
|
1922
|
+
leaseToken: number;
|
|
1923
|
+
leaseDurationMs: number;
|
|
1924
|
+
now?: Date;
|
|
1925
|
+
}): Promise<boolean>;
|
|
1926
|
+
/**
|
|
1927
|
+
* The UPDATE needs a row lock that conflicts with the `FOR SHARE` lock the
|
|
1928
|
+
* fenced child insert takes on this row, so it waits for an in-flight
|
|
1929
|
+
* insert to commit. A fenced insert under the old token that reaches the
|
|
1930
|
+
* row while this rotation is uncommitted waits for it, rechecks the new row
|
|
1931
|
+
* version and inserts nothing (live tests "orders a token rotation after an
|
|
1932
|
+
* in-flight fenced create ..." and "refuses a fenced create under the old
|
|
1933
|
+
* token once a token rotation is ordered before it").
|
|
1934
|
+
*/
|
|
1935
|
+
rotateStagedInvocationLease(input: {
|
|
1936
|
+
id: string;
|
|
1937
|
+
workerId: string;
|
|
1938
|
+
leaseToken: number;
|
|
1939
|
+
leaseDurationMs: number;
|
|
1940
|
+
now?: Date;
|
|
1941
|
+
}): Promise<number | undefined>;
|
|
1942
|
+
cancelStagedInvocationsForFailedParents(input?: {
|
|
1943
|
+
tenantId?: string;
|
|
1944
|
+
spaceId?: string;
|
|
1945
|
+
now?: Date;
|
|
1946
|
+
}): Promise<number>;
|
|
1947
|
+
listStagedInvocations(input: {
|
|
1948
|
+
tenantId: string;
|
|
1949
|
+
spaceId: string;
|
|
1950
|
+
parentInvocationId?: string;
|
|
1951
|
+
statuses?: readonly StagedInvocationStatus[];
|
|
1952
|
+
}): Promise<StagedInvocationRecord[]>;
|
|
1953
|
+
private settleStagedInvocation;
|
|
1634
1954
|
nextEventSequence(tenantId: string, spaceId: string): Promise<number>;
|
|
1635
1955
|
getEntityStateSource(tenantId: string, spaceId: string, entityType: string, entityId: string): Promise<{
|
|
1636
1956
|
state: string;
|
|
@@ -1764,6 +2084,28 @@ export interface CreateDurableSagaParentLifecycleOptions<TDb> {
|
|
|
1764
2084
|
*/
|
|
1765
2085
|
export declare function createDurableSagaParentLifecycle<TDb>(options: CreateDurableSagaParentLifecycleOptions<TDb>): HostSagaParentLifecycle;
|
|
1766
2086
|
//#endregion
|
|
2087
|
+
//#region src/staged-invocations.d.ts
|
|
2088
|
+
export declare const MAX_STAGED_INVOCATIONS = 32;
|
|
2089
|
+
export declare const MAX_STAGED_INVOCATION_KEY_LENGTH = 128;
|
|
2090
|
+
export declare const MAX_STAGED_INVOCATION_BYTES: number;
|
|
2091
|
+
export declare const MAX_STAGED_INVOCATION_BATCH_BYTES: number;
|
|
2092
|
+
export declare const STAGED_INVOCATION_KEY_PATTERN: RegExp;
|
|
2093
|
+
interface PrepareStagedInvocationBatchInput<TDb> {
|
|
2094
|
+
parent: Pick<ActionInvocationRecord, "id" | "tenantId" | "spaceId" | "actionId">;
|
|
2095
|
+
parentAction: ActionDefinition<TDb>;
|
|
2096
|
+
requests: readonly StagedInvocationRequest[];
|
|
2097
|
+
resolveAction(actionId: ActionId): ActionDefinition<TDb> | undefined;
|
|
2098
|
+
redactParameters?(actionId: ActionId, parameters: Record<string, unknown>): Record<string, unknown>;
|
|
2099
|
+
/** Keys whose parameters already passed the redactor into a durable checkpoint. */
|
|
2100
|
+
redactedKeys?: readonly string[];
|
|
2101
|
+
now: Date;
|
|
2102
|
+
}
|
|
2103
|
+
/** Validate and normalize one immutable batch before its parent transaction commits. */
|
|
2104
|
+
export declare function prepareStagedInvocationBatch<TDb>(input: PrepareStagedInvocationBatchInput<TDb>): StagedInvocationRecord[];
|
|
2105
|
+
export declare function stagedInvocationRequestIdentity(record: StagedInvocationRecord): string;
|
|
2106
|
+
export declare function cloneStagedInvocationRecord(record: StagedInvocationRecord): StagedInvocationRecord;
|
|
2107
|
+
export declare function asStagedInvocationStore<TDb>(store: PlatformHostStore<TDb>): StagedInvocationPlatformHostStore<TDb> | undefined;
|
|
2108
|
+
//#endregion
|
|
1767
2109
|
//#region src/tenant-isolation.d.ts
|
|
1768
2110
|
export interface TenantIsolationScope {
|
|
1769
2111
|
tenantId: string;
|
|
@@ -1801,7 +2143,7 @@ export interface TenantIsolationSubject<TDb = unknown> {
|
|
|
1801
2143
|
reset?(): Promise<void> | void;
|
|
1802
2144
|
}
|
|
1803
2145
|
export interface TenantIsolationCheck {
|
|
1804
|
-
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.completion-scoped.v1" | "fabric.tenancy.projection-scoped.v1" | "fabric.tenancy.adapter-invocation-read-scoped.v1" | "fabric.tenancy.adapter-invocation-write-scoped.v1";
|
|
2146
|
+
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";
|
|
1805
2147
|
run(subject: TenantIsolationSubject): Promise<string[]>;
|
|
1806
2148
|
}
|
|
1807
2149
|
export interface TenantIsolationResult {
|
|
@@ -1814,15 +2156,16 @@ export interface TenantIsolationResult {
|
|
|
1814
2156
|
}>;
|
|
1815
2157
|
}
|
|
1816
2158
|
/**
|
|
1817
|
-
* The suite
|
|
2159
|
+
* The suite a deployment of the host must pass before it claims isolation.
|
|
1818
2160
|
*
|
|
1819
|
-
*
|
|
2161
|
+
* Nine checks: an invocation cannot be read, executed, or completed under
|
|
1820
2162
|
* another tenant's scope; an idempotency key is a tenant's own, so the same
|
|
1821
2163
|
* key in two tenants is two invocations; a tenant's event stream carries no
|
|
1822
2164
|
* other tenant's events; a worker scoped to one tenant does not claim another's
|
|
1823
|
-
* work;
|
|
1824
|
-
*
|
|
1825
|
-
* the
|
|
2165
|
+
* work; staged listing and claiming retain tenant and space scope; an adapter
|
|
2166
|
+
* checkpoint cannot be read or written under another tenant, space, or owning
|
|
2167
|
+
* invocation; and, when the subject lends a read, a viewer in the other tenant
|
|
2168
|
+
* sees nothing of ours.
|
|
1826
2169
|
*/
|
|
1827
2170
|
export declare function tenantIsolationChecks(): readonly TenantIsolationCheck[];
|
|
1828
2171
|
/** Run every check, returning each result rather than throwing on the first. */
|