@fabricorg/platform-host 8.4.0 → 8.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +34 -0
- package/README.md +117 -4
- package/dist/index.cjs +579 -158
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +129 -5
- package/dist/index.d.ts +129 -5
- package/dist/index.js +576 -159
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/dist/index.d.cts
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, StagedInvocationRequest, canonicalJson } from "@fabricorg/platform";
|
|
1
|
+
import { ActionDefinition, ActionId, ActionStatus, ActorType, AdapterCircuitBreakerProvider, AdapterImplementation, AgentActionPolicyDecision, 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. */
|
|
@@ -251,7 +251,7 @@ export interface PendingAssetEvent {
|
|
|
251
251
|
}
|
|
252
252
|
/** JSON preparation committed with the handler before adapter execution. */
|
|
253
253
|
export interface FinalizationCheckpoint {
|
|
254
|
-
protocol: "atomic-after-adapters-v1";
|
|
254
|
+
protocol: "atomic-after-adapters-v1" | "atomic-after-adapters-v2";
|
|
255
255
|
actionVersion: number;
|
|
256
256
|
steps: {
|
|
257
257
|
adapterType: string;
|
|
@@ -259,6 +259,8 @@ export interface FinalizationCheckpoint {
|
|
|
259
259
|
}[];
|
|
260
260
|
params: import("@fabricorg/platform").FinalizationJson;
|
|
261
261
|
handlerData: import("@fabricorg/platform").FinalizationRecord;
|
|
262
|
+
/** Private adapter input preparation; retained until settlement, including reconciliation. */
|
|
263
|
+
adapterPreparation?: import("@fabricorg/platform").FinalizationRecord;
|
|
262
264
|
handlerEvents: (Omit<PendingAssetEvent, "payload"> & {
|
|
263
265
|
payload: import("@fabricorg/platform").FinalizationJson;
|
|
264
266
|
})[];
|
|
@@ -337,6 +339,11 @@ export interface ActionInvocationRecord {
|
|
|
337
339
|
hitlReason?: string;
|
|
338
340
|
hitlPolicyVersion?: string;
|
|
339
341
|
approvalDecision?: PersistedActionApprovalDecision;
|
|
342
|
+
approvalExpiresAt?: Date;
|
|
343
|
+
approvalExpiry?: {
|
|
344
|
+
expiresAt: Date;
|
|
345
|
+
expiredAt: Date;
|
|
346
|
+
};
|
|
340
347
|
mutationFootprint?: MutationFootprint;
|
|
341
348
|
executionPrincipal?: ExecutionPrincipal;
|
|
342
349
|
runtimeEvidence?: GovernanceRuntimeEvidence;
|
|
@@ -359,14 +366,50 @@ export interface AuthorizationReconciliationOutcome {
|
|
|
359
366
|
provenance?: Omit<InvocationProvenance, "traceAttributes">;
|
|
360
367
|
message: string;
|
|
361
368
|
}
|
|
369
|
+
export interface HostHitlDecision extends AgentActionPolicyDecision {
|
|
370
|
+
/** Absolute approval deadline; a valid Date, including a deadline already due. */
|
|
371
|
+
approvalExpiresAt?: Date;
|
|
372
|
+
}
|
|
362
373
|
export interface HitlDecisionEvidence {
|
|
374
|
+
approvalExpiresAt?: Date;
|
|
363
375
|
route: AgentActionRoute;
|
|
364
376
|
riskTier: AgentActionRiskTier;
|
|
365
377
|
reason: string;
|
|
366
378
|
policyVersion?: string;
|
|
367
379
|
evaluatedAt: Date;
|
|
368
380
|
}
|
|
381
|
+
export type ApprovalEvidenceValue = null | boolean | number | string | ApprovalEvidenceValue[] | {
|
|
382
|
+
[key: string]: ApprovalEvidenceValue;
|
|
383
|
+
};
|
|
384
|
+
export type ApprovalEvidence = {
|
|
385
|
+
[key: string]: ApprovalEvidenceValue;
|
|
386
|
+
};
|
|
387
|
+
/** Maximum serialized UTF-8 evidence size. */
|
|
388
|
+
export declare const MAX_APPROVAL_EVIDENCE_BYTES: number;
|
|
389
|
+
export declare const APPROVAL_REQUESTED_EVENT: "ApprovalRequested";
|
|
390
|
+
export declare const APPROVAL_DECIDED_EVENT: "ApprovalDecided";
|
|
391
|
+
export declare const APPROVAL_EXPIRED_EVENT: "ApprovalExpired";
|
|
392
|
+
export interface ApprovalRequestedPayload {
|
|
393
|
+
route: AgentActionRoute;
|
|
394
|
+
riskTier: AgentActionRiskTier;
|
|
395
|
+
reason: string;
|
|
396
|
+
expiresAt?: string;
|
|
397
|
+
}
|
|
398
|
+
export interface ApprovalDecidedPayload {
|
|
399
|
+
approved: boolean;
|
|
400
|
+
approverId: string;
|
|
401
|
+
approverType: ActorType;
|
|
402
|
+
reason?: string;
|
|
403
|
+
decidedAt: string;
|
|
404
|
+
evidencePresent: boolean;
|
|
405
|
+
}
|
|
406
|
+
export interface ApprovalExpiredPayload {
|
|
407
|
+
expiresAt: string;
|
|
408
|
+
expiredAt: string;
|
|
409
|
+
}
|
|
369
410
|
export interface ActionApprovalDecision {
|
|
411
|
+
/** Verification references only; credentials and tokens must not be included. */
|
|
412
|
+
evidence?: ApprovalEvidence;
|
|
370
413
|
approved: boolean;
|
|
371
414
|
approverId: string;
|
|
372
415
|
approverType: ActorType;
|
|
@@ -625,6 +668,8 @@ export interface PlatformHostStore<TDb> {
|
|
|
625
668
|
* back when `run` throws.
|
|
626
669
|
*/
|
|
627
670
|
export interface PlatformHostMutationTransaction<TDb> {
|
|
671
|
+
/** Conditional SQL approval write on the transaction connection; lifecycle events are appended by the caller in this unit of work. */
|
|
672
|
+
beginApprovalDecision?(input: Omit<BeginApprovalDecisionInput, "lifecycleEvent">): Promise<ApprovalDecisionTransitionResult>;
|
|
628
673
|
readonly db: TDb;
|
|
629
674
|
/**
|
|
630
675
|
* Read and lock an invocation until this transaction completes.
|
|
@@ -1059,7 +1104,34 @@ export interface OutboxRequeueAuthorizationInput {
|
|
|
1059
1104
|
export interface AtomicMutationPlatformHostStore<TDb> extends PlatformHostStore<TDb> {
|
|
1060
1105
|
transactionWithEvents<TResult>(run: (transaction: PlatformHostMutationTransaction<TDb>) => Promise<TResult>): Promise<TResult>;
|
|
1061
1106
|
}
|
|
1107
|
+
export interface ApprovalLifecycleEvent {
|
|
1108
|
+
event: AssetEventEnvelope;
|
|
1109
|
+
metadata: OutboxEventMetadata;
|
|
1110
|
+
}
|
|
1111
|
+
/** Called within the transition transaction. Must be pure and return audit-safe data. Sequence is assigned by the store. */
|
|
1112
|
+
export type ApprovalLifecycleEventFactory = (invocation: ActionInvocationRecord, kind: "requested" | "decided" | "expired") => ApprovalLifecycleEvent;
|
|
1113
|
+
export interface ExpireDueApprovalsInput {
|
|
1114
|
+
tenantId?: string;
|
|
1115
|
+
spaceId?: string;
|
|
1116
|
+
now?: Date;
|
|
1117
|
+
limit?: number;
|
|
1118
|
+
}
|
|
1119
|
+
export interface ExpireDueApprovalsStoreInput extends ExpireDueApprovalsInput {
|
|
1120
|
+
now: Date;
|
|
1121
|
+
lifecycleEvent?: ApprovalLifecycleEventFactory;
|
|
1122
|
+
}
|
|
1123
|
+
export interface ParkApprovalInput {
|
|
1124
|
+
approvalExpiresAt?: Date;
|
|
1125
|
+
actionInvocationId: string;
|
|
1126
|
+
tenantId: string;
|
|
1127
|
+
spaceId: string;
|
|
1128
|
+
now: Date;
|
|
1129
|
+
leaseOwner?: string;
|
|
1130
|
+
leaseToken?: number;
|
|
1131
|
+
lifecycleEvent?: ApprovalLifecycleEventFactory;
|
|
1132
|
+
}
|
|
1062
1133
|
export interface BeginApprovalDecisionInput {
|
|
1134
|
+
lifecycleEvent?: ApprovalLifecycleEventFactory;
|
|
1063
1135
|
actionInvocationId: string;
|
|
1064
1136
|
tenantId: string;
|
|
1065
1137
|
spaceId: string;
|
|
@@ -1074,7 +1146,37 @@ export interface ApprovalDecisionTransitionResult {
|
|
|
1074
1146
|
}
|
|
1075
1147
|
/** Optional store capability required only when agent HITL or approval resume is used. */
|
|
1076
1148
|
export interface ApprovalPlatformHostStore<TDb> extends PlatformHostStore<TDb> {
|
|
1149
|
+
/** True only when approval transitions and lifecycle outbox events share a transaction. */
|
|
1150
|
+
readonly transactionalApprovalLifecycle?: boolean;
|
|
1151
|
+
/**
|
|
1152
|
+
* Conditionally park an executable invocation only with its matching lease owner/generation
|
|
1153
|
+
* (when leased) and no prior approval decision. Persist the deadline supplied in input.
|
|
1154
|
+
* Serialize with beginApprovalDecision and expireDueApprovals so each waiting row settles
|
|
1155
|
+
* exactly once across concurrent decisions and sweeps; losing transitions report applied: false.
|
|
1156
|
+
* When lifecycleEvent is supplied, its event/outbox writes and the state change must commit
|
|
1157
|
+
* in the same atomic unit of work, or roll back together.
|
|
1158
|
+
*/
|
|
1159
|
+
parkApproval?(input: ParkApprovalInput): Promise<ApprovalDecisionTransitionResult>;
|
|
1160
|
+
/**
|
|
1161
|
+
* Atomically claim and expire scoped waiting rows whose input.now >= approvalExpiresAt.
|
|
1162
|
+
* Set failed with approvalExpiry and no approvalDecision. Each waiting row must settle
|
|
1163
|
+
* exactly once across concurrent sweeps and beginApprovalDecision calls; return only rows
|
|
1164
|
+
* this sweep settled (competing decision transitions report applied: false).
|
|
1165
|
+
* When lifecycleEvent is supplied, the events/outbox writes and state changes must commit
|
|
1166
|
+
* in the same atomic unit of work, or roll back together.
|
|
1167
|
+
*/
|
|
1168
|
+
expireDueApprovals?(input: ExpireDueApprovalsStoreInput): Promise<ActionInvocationRecord[]>;
|
|
1077
1169
|
recordHitlDecision(actionInvocationId: string, tenantId: string, spaceId: string, decision: HitlDecisionEvidence): Promise<ActionInvocationRecord>;
|
|
1170
|
+
/**
|
|
1171
|
+
* Atomically decide a waiting row, comparing the stored deadline with input.now inside
|
|
1172
|
+
* the serialized transition. A decision at or after that deadline (input.now >=
|
|
1173
|
+
* approvalExpiresAt) must never be applied: expire the row to failed with approvalExpiry
|
|
1174
|
+
* and no approvalDecision instead. The caller's decision.decidedAt does not extend it.
|
|
1175
|
+
* Each waiting row must settle exactly once across concurrent decisions and expiry sweeps;
|
|
1176
|
+
* a losing transition reports applied: false. With lifecycleEvent, the selected decided
|
|
1177
|
+
* or expired event/outbox writes and state change must commit in the same atomic unit
|
|
1178
|
+
* of work, or roll back together. Required when implementing parkApproval/expireDueApprovals.
|
|
1179
|
+
*/
|
|
1078
1180
|
beginApprovalDecision(input: BeginApprovalDecisionInput): Promise<ApprovalDecisionTransitionResult>;
|
|
1079
1181
|
}
|
|
1080
1182
|
/** Optional durable capabilities used when external-governance enrichment is configured. */
|
|
@@ -1124,7 +1226,7 @@ export interface ClaimActionInvocationsInput {
|
|
|
1124
1226
|
* - `claimActionInvocations` must never claim a running invocation without a
|
|
1125
1227
|
* lease, which is what a parked invocation is.
|
|
1126
1228
|
*/
|
|
1127
|
-
export type ActionInvocationPatch = Partial<Pick<ActionInvocationRecord, "finalizationCheckpoint" | "deferredBeforeEffectAttempt" | "status" | "result" | "error" | "authorizationReconciliation" | "adapterReconciliation" | "pendingStateTransition" | "pendingCompletion" | "externalCompletion">>;
|
|
1229
|
+
export type ActionInvocationPatch = Partial<Pick<ActionInvocationRecord, "approvalExpiresAt" | "approvalExpiry" | "approvalDecision" | "leaseOwner" | "leaseExpiresAt" | "leaseToken" | "attemptCount" | "finalizationCheckpoint" | "deferredBeforeEffectAttempt" | "status" | "result" | "error" | "authorizationReconciliation" | "adapterReconciliation" | "pendingStateTransition" | "pendingCompletion" | "externalCompletion">>;
|
|
1128
1230
|
export interface UpdateLeasedActionInvocationInput {
|
|
1129
1231
|
id: string;
|
|
1130
1232
|
tenantId: string;
|
|
@@ -1322,6 +1424,8 @@ export interface PlatformActionWorkerCycleResult {
|
|
|
1322
1424
|
failed: number;
|
|
1323
1425
|
/** Present when claimed agent work was durably parked instead of failing. */
|
|
1324
1426
|
waitingForApproval?: number;
|
|
1427
|
+
/** Due approval waits settled to failed during this cycle; present when positive. */
|
|
1428
|
+
expiredApprovals?: number;
|
|
1325
1429
|
/**
|
|
1326
1430
|
* Present only when > 0: claimed invocations whose execution threw a
|
|
1327
1431
|
* RetryableExecutionError (counted by error type, not by where it was thrown).
|
|
@@ -1446,7 +1550,11 @@ export interface PlatformHostOptions<TDb> {
|
|
|
1446
1550
|
shouldPublish?(event: AssetEventEnvelope): boolean;
|
|
1447
1551
|
};
|
|
1448
1552
|
/** Optional vertical-owned evaluator. When absent, agent behavior is unchanged. */
|
|
1449
|
-
hitlEvaluator?: AgentActionPolicyEvaluator
|
|
1553
|
+
hitlEvaluator?: (context: Parameters<AgentActionPolicyEvaluator>[0]) => HostHitlDecision | Promise<HostHitlDecision>;
|
|
1554
|
+
/** Positive integer milliseconds, used when the evaluator supplies no absolute deadline. */
|
|
1555
|
+
approvalDefaultTtlMs?: number;
|
|
1556
|
+
/** Atomic approval lifecycle events and outbox writes; defaults to false. */
|
|
1557
|
+
approvalLifecycleEvents?: boolean;
|
|
1450
1558
|
/** Durable evaluator/ruleset version recorded with every HITL decision. */
|
|
1451
1559
|
hitlPolicyVersion?: string;
|
|
1452
1560
|
/** Optional portable resolver; provider-specific implementations belong in integration packages. */
|
|
@@ -1560,7 +1668,15 @@ export interface PlatformHostOptions<TDb> {
|
|
|
1560
1668
|
*/
|
|
1561
1669
|
adapterDeadlineMs?: number;
|
|
1562
1670
|
}
|
|
1671
|
+
export interface ApprovalExpiryHost {
|
|
1672
|
+
expireDueApprovals(input?: ExpireDueApprovalsInput): Promise<{
|
|
1673
|
+
expired: string[];
|
|
1674
|
+
}>;
|
|
1675
|
+
}
|
|
1563
1676
|
export interface GovernedActionHost {
|
|
1677
|
+
expireDueApprovals?(input?: ExpireDueApprovalsInput): Promise<{
|
|
1678
|
+
expired: string[];
|
|
1679
|
+
}>;
|
|
1564
1680
|
submitAction(input: SubmitActionInput): Promise<SubmitActionResult>;
|
|
1565
1681
|
/** Whether this Host's registry contains an action with a non-empty staged-descendant allowlist. */
|
|
1566
1682
|
readonly hasStagedInvocationActions?: boolean;
|
|
@@ -1605,7 +1721,7 @@ export interface OutboxRequeueHost {
|
|
|
1605
1721
|
}
|
|
1606
1722
|
//#endregion
|
|
1607
1723
|
//#region src/host.d.ts
|
|
1608
|
-
export declare function createGovernedActionHost<TDb>(options: PlatformHostOptions<TDb>): GovernedActionHost & OutboxRequeueHost;
|
|
1724
|
+
export declare function createGovernedActionHost<TDb>(options: PlatformHostOptions<TDb>): GovernedActionHost & OutboxRequeueHost & ApprovalExpiryHost;
|
|
1609
1725
|
//#endregion
|
|
1610
1726
|
//#region src/memory-store.d.ts
|
|
1611
1727
|
export interface MemoryPlatformHostTransactionProvider<TDb> {
|
|
@@ -1615,6 +1731,8 @@ export interface MemoryPlatformHostTransactionProvider<TDb> {
|
|
|
1615
1731
|
export declare class MemoryPlatformHostStore<TDb> implements RecoverablePlatformHostStore<TDb>, ApprovalPlatformHostStore<TDb>, GovernancePlatformHostStore<TDb>, OutboxPlatformHostStore<TDb>, OutboxRequeuePlatformHostStore<TDb>, StagedInvocationPlatformHostStore<TDb> {
|
|
1616
1732
|
readonly db: TDb;
|
|
1617
1733
|
readonly transactionalOutbox: boolean;
|
|
1734
|
+
readonly transactionalApprovalLifecycle: boolean;
|
|
1735
|
+
private readonly approvalTransactionProvider;
|
|
1618
1736
|
readonly transactionalStagedInvocations: boolean;
|
|
1619
1737
|
transactionWithEvents?: <TResult>(run: (transaction: PlatformHostMutationTransaction<TDb>) => Promise<TResult>) => Promise<TResult>;
|
|
1620
1738
|
private adapterCommit;
|
|
@@ -1645,7 +1763,10 @@ export declare class MemoryPlatformHostStore<TDb> implements RecoverablePlatform
|
|
|
1645
1763
|
getActionInvocationByStagedOrigin(tenantId: string, spaceId: string, origin: StagedInvocationOrigin): Promise<ActionInvocationRecord | undefined>;
|
|
1646
1764
|
updateActionInvocation(id: string, tenantId: string, spaceId: string, patch: ActionInvocationPatch): Promise<void>;
|
|
1647
1765
|
recordHitlDecision(actionInvocationId: string, tenantId: string, spaceId: string, decision: HitlDecisionEvidence): Promise<ActionInvocationRecord>;
|
|
1766
|
+
private runApprovalTransaction;
|
|
1767
|
+
parkApproval(input: ParkApprovalInput): Promise<ApprovalDecisionTransitionResult>;
|
|
1648
1768
|
beginApprovalDecision(input: BeginApprovalDecisionInput): Promise<ApprovalDecisionTransitionResult>;
|
|
1769
|
+
expireDueApprovals(input: ExpireDueApprovalsStoreInput): Promise<ActionInvocationRecord[]>;
|
|
1649
1770
|
appendPolicyEvaluation(record: PolicyEvaluationRecord): Promise<void>;
|
|
1650
1771
|
recordMutationGovernance(actionInvocationId: string, tenantId: string, spaceId: string, context: Pick<ActionInvocationRecord, "mutationFootprint" | "executionPrincipal"> & {
|
|
1651
1772
|
footprint: NonNullable<ActionInvocationRecord["mutationFootprint"]>;
|
|
@@ -1832,6 +1953,7 @@ export declare class PostgresPlatformHostStore<TDb> implements RecoverablePlatfo
|
|
|
1832
1953
|
private readonly sql;
|
|
1833
1954
|
readonly transactionWithEvents?: AtomicMutationPlatformHostStore<TDb>["transactionWithEvents"];
|
|
1834
1955
|
readonly transactionalOutbox: boolean;
|
|
1956
|
+
readonly transactionalApprovalLifecycle: boolean;
|
|
1835
1957
|
readonly transactionalStagedInvocations: boolean;
|
|
1836
1958
|
constructor(db: TDb, sql: PlatformHostSqlClient, transactionProvider?: PostgresPlatformHostTransactionProvider<TDb>);
|
|
1837
1959
|
ensureSchema(): Promise<void>;
|
|
@@ -1843,6 +1965,8 @@ export declare class PostgresPlatformHostStore<TDb> implements RecoverablePlatfo
|
|
|
1843
1965
|
getActionInvocationByStagedOrigin(tenantId: string, spaceId: string, origin: StagedInvocationOrigin): Promise<ActionInvocationRecord | undefined>;
|
|
1844
1966
|
updateActionInvocation(id: string, tenantId: string, spaceId: string, patch: ActionInvocationPatch): Promise<void>;
|
|
1845
1967
|
recordHitlDecision(actionInvocationId: string, tenantId: string, spaceId: string, decision: HitlDecisionEvidence): Promise<ActionInvocationRecord>;
|
|
1968
|
+
parkApproval(input: ParkApprovalInput): Promise<ApprovalDecisionTransitionResult>;
|
|
1969
|
+
expireDueApprovals(input: ExpireDueApprovalsStoreInput): Promise<ActionInvocationRecord[]>;
|
|
1846
1970
|
beginApprovalDecision(input: BeginApprovalDecisionInput): Promise<ApprovalDecisionTransitionResult>;
|
|
1847
1971
|
appendPolicyEvaluation(record: PolicyEvaluationRecord): Promise<void>;
|
|
1848
1972
|
recordMutationGovernance(actionInvocationId: string, tenantId: string, spaceId: string, context: {
|
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, StagedInvocationRequest, canonicalJson } from "@fabricorg/platform";
|
|
1
|
+
import { ActionDefinition, ActionId, ActionStatus, ActorType, AdapterCircuitBreakerProvider, AdapterImplementation, AgentActionPolicyDecision, 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. */
|
|
@@ -251,7 +251,7 @@ export interface PendingAssetEvent {
|
|
|
251
251
|
}
|
|
252
252
|
/** JSON preparation committed with the handler before adapter execution. */
|
|
253
253
|
export interface FinalizationCheckpoint {
|
|
254
|
-
protocol: "atomic-after-adapters-v1";
|
|
254
|
+
protocol: "atomic-after-adapters-v1" | "atomic-after-adapters-v2";
|
|
255
255
|
actionVersion: number;
|
|
256
256
|
steps: {
|
|
257
257
|
adapterType: string;
|
|
@@ -259,6 +259,8 @@ export interface FinalizationCheckpoint {
|
|
|
259
259
|
}[];
|
|
260
260
|
params: import("@fabricorg/platform").FinalizationJson;
|
|
261
261
|
handlerData: import("@fabricorg/platform").FinalizationRecord;
|
|
262
|
+
/** Private adapter input preparation; retained until settlement, including reconciliation. */
|
|
263
|
+
adapterPreparation?: import("@fabricorg/platform").FinalizationRecord;
|
|
262
264
|
handlerEvents: (Omit<PendingAssetEvent, "payload"> & {
|
|
263
265
|
payload: import("@fabricorg/platform").FinalizationJson;
|
|
264
266
|
})[];
|
|
@@ -337,6 +339,11 @@ export interface ActionInvocationRecord {
|
|
|
337
339
|
hitlReason?: string;
|
|
338
340
|
hitlPolicyVersion?: string;
|
|
339
341
|
approvalDecision?: PersistedActionApprovalDecision;
|
|
342
|
+
approvalExpiresAt?: Date;
|
|
343
|
+
approvalExpiry?: {
|
|
344
|
+
expiresAt: Date;
|
|
345
|
+
expiredAt: Date;
|
|
346
|
+
};
|
|
340
347
|
mutationFootprint?: MutationFootprint;
|
|
341
348
|
executionPrincipal?: ExecutionPrincipal;
|
|
342
349
|
runtimeEvidence?: GovernanceRuntimeEvidence;
|
|
@@ -359,14 +366,50 @@ export interface AuthorizationReconciliationOutcome {
|
|
|
359
366
|
provenance?: Omit<InvocationProvenance, "traceAttributes">;
|
|
360
367
|
message: string;
|
|
361
368
|
}
|
|
369
|
+
export interface HostHitlDecision extends AgentActionPolicyDecision {
|
|
370
|
+
/** Absolute approval deadline; a valid Date, including a deadline already due. */
|
|
371
|
+
approvalExpiresAt?: Date;
|
|
372
|
+
}
|
|
362
373
|
export interface HitlDecisionEvidence {
|
|
374
|
+
approvalExpiresAt?: Date;
|
|
363
375
|
route: AgentActionRoute;
|
|
364
376
|
riskTier: AgentActionRiskTier;
|
|
365
377
|
reason: string;
|
|
366
378
|
policyVersion?: string;
|
|
367
379
|
evaluatedAt: Date;
|
|
368
380
|
}
|
|
381
|
+
export type ApprovalEvidenceValue = null | boolean | number | string | ApprovalEvidenceValue[] | {
|
|
382
|
+
[key: string]: ApprovalEvidenceValue;
|
|
383
|
+
};
|
|
384
|
+
export type ApprovalEvidence = {
|
|
385
|
+
[key: string]: ApprovalEvidenceValue;
|
|
386
|
+
};
|
|
387
|
+
/** Maximum serialized UTF-8 evidence size. */
|
|
388
|
+
export declare const MAX_APPROVAL_EVIDENCE_BYTES: number;
|
|
389
|
+
export declare const APPROVAL_REQUESTED_EVENT: "ApprovalRequested";
|
|
390
|
+
export declare const APPROVAL_DECIDED_EVENT: "ApprovalDecided";
|
|
391
|
+
export declare const APPROVAL_EXPIRED_EVENT: "ApprovalExpired";
|
|
392
|
+
export interface ApprovalRequestedPayload {
|
|
393
|
+
route: AgentActionRoute;
|
|
394
|
+
riskTier: AgentActionRiskTier;
|
|
395
|
+
reason: string;
|
|
396
|
+
expiresAt?: string;
|
|
397
|
+
}
|
|
398
|
+
export interface ApprovalDecidedPayload {
|
|
399
|
+
approved: boolean;
|
|
400
|
+
approverId: string;
|
|
401
|
+
approverType: ActorType;
|
|
402
|
+
reason?: string;
|
|
403
|
+
decidedAt: string;
|
|
404
|
+
evidencePresent: boolean;
|
|
405
|
+
}
|
|
406
|
+
export interface ApprovalExpiredPayload {
|
|
407
|
+
expiresAt: string;
|
|
408
|
+
expiredAt: string;
|
|
409
|
+
}
|
|
369
410
|
export interface ActionApprovalDecision {
|
|
411
|
+
/** Verification references only; credentials and tokens must not be included. */
|
|
412
|
+
evidence?: ApprovalEvidence;
|
|
370
413
|
approved: boolean;
|
|
371
414
|
approverId: string;
|
|
372
415
|
approverType: ActorType;
|
|
@@ -625,6 +668,8 @@ export interface PlatformHostStore<TDb> {
|
|
|
625
668
|
* back when `run` throws.
|
|
626
669
|
*/
|
|
627
670
|
export interface PlatformHostMutationTransaction<TDb> {
|
|
671
|
+
/** Conditional SQL approval write on the transaction connection; lifecycle events are appended by the caller in this unit of work. */
|
|
672
|
+
beginApprovalDecision?(input: Omit<BeginApprovalDecisionInput, "lifecycleEvent">): Promise<ApprovalDecisionTransitionResult>;
|
|
628
673
|
readonly db: TDb;
|
|
629
674
|
/**
|
|
630
675
|
* Read and lock an invocation until this transaction completes.
|
|
@@ -1059,7 +1104,34 @@ export interface OutboxRequeueAuthorizationInput {
|
|
|
1059
1104
|
export interface AtomicMutationPlatformHostStore<TDb> extends PlatformHostStore<TDb> {
|
|
1060
1105
|
transactionWithEvents<TResult>(run: (transaction: PlatformHostMutationTransaction<TDb>) => Promise<TResult>): Promise<TResult>;
|
|
1061
1106
|
}
|
|
1107
|
+
export interface ApprovalLifecycleEvent {
|
|
1108
|
+
event: AssetEventEnvelope;
|
|
1109
|
+
metadata: OutboxEventMetadata;
|
|
1110
|
+
}
|
|
1111
|
+
/** Called within the transition transaction. Must be pure and return audit-safe data. Sequence is assigned by the store. */
|
|
1112
|
+
export type ApprovalLifecycleEventFactory = (invocation: ActionInvocationRecord, kind: "requested" | "decided" | "expired") => ApprovalLifecycleEvent;
|
|
1113
|
+
export interface ExpireDueApprovalsInput {
|
|
1114
|
+
tenantId?: string;
|
|
1115
|
+
spaceId?: string;
|
|
1116
|
+
now?: Date;
|
|
1117
|
+
limit?: number;
|
|
1118
|
+
}
|
|
1119
|
+
export interface ExpireDueApprovalsStoreInput extends ExpireDueApprovalsInput {
|
|
1120
|
+
now: Date;
|
|
1121
|
+
lifecycleEvent?: ApprovalLifecycleEventFactory;
|
|
1122
|
+
}
|
|
1123
|
+
export interface ParkApprovalInput {
|
|
1124
|
+
approvalExpiresAt?: Date;
|
|
1125
|
+
actionInvocationId: string;
|
|
1126
|
+
tenantId: string;
|
|
1127
|
+
spaceId: string;
|
|
1128
|
+
now: Date;
|
|
1129
|
+
leaseOwner?: string;
|
|
1130
|
+
leaseToken?: number;
|
|
1131
|
+
lifecycleEvent?: ApprovalLifecycleEventFactory;
|
|
1132
|
+
}
|
|
1062
1133
|
export interface BeginApprovalDecisionInput {
|
|
1134
|
+
lifecycleEvent?: ApprovalLifecycleEventFactory;
|
|
1063
1135
|
actionInvocationId: string;
|
|
1064
1136
|
tenantId: string;
|
|
1065
1137
|
spaceId: string;
|
|
@@ -1074,7 +1146,37 @@ export interface ApprovalDecisionTransitionResult {
|
|
|
1074
1146
|
}
|
|
1075
1147
|
/** Optional store capability required only when agent HITL or approval resume is used. */
|
|
1076
1148
|
export interface ApprovalPlatformHostStore<TDb> extends PlatformHostStore<TDb> {
|
|
1149
|
+
/** True only when approval transitions and lifecycle outbox events share a transaction. */
|
|
1150
|
+
readonly transactionalApprovalLifecycle?: boolean;
|
|
1151
|
+
/**
|
|
1152
|
+
* Conditionally park an executable invocation only with its matching lease owner/generation
|
|
1153
|
+
* (when leased) and no prior approval decision. Persist the deadline supplied in input.
|
|
1154
|
+
* Serialize with beginApprovalDecision and expireDueApprovals so each waiting row settles
|
|
1155
|
+
* exactly once across concurrent decisions and sweeps; losing transitions report applied: false.
|
|
1156
|
+
* When lifecycleEvent is supplied, its event/outbox writes and the state change must commit
|
|
1157
|
+
* in the same atomic unit of work, or roll back together.
|
|
1158
|
+
*/
|
|
1159
|
+
parkApproval?(input: ParkApprovalInput): Promise<ApprovalDecisionTransitionResult>;
|
|
1160
|
+
/**
|
|
1161
|
+
* Atomically claim and expire scoped waiting rows whose input.now >= approvalExpiresAt.
|
|
1162
|
+
* Set failed with approvalExpiry and no approvalDecision. Each waiting row must settle
|
|
1163
|
+
* exactly once across concurrent sweeps and beginApprovalDecision calls; return only rows
|
|
1164
|
+
* this sweep settled (competing decision transitions report applied: false).
|
|
1165
|
+
* When lifecycleEvent is supplied, the events/outbox writes and state changes must commit
|
|
1166
|
+
* in the same atomic unit of work, or roll back together.
|
|
1167
|
+
*/
|
|
1168
|
+
expireDueApprovals?(input: ExpireDueApprovalsStoreInput): Promise<ActionInvocationRecord[]>;
|
|
1077
1169
|
recordHitlDecision(actionInvocationId: string, tenantId: string, spaceId: string, decision: HitlDecisionEvidence): Promise<ActionInvocationRecord>;
|
|
1170
|
+
/**
|
|
1171
|
+
* Atomically decide a waiting row, comparing the stored deadline with input.now inside
|
|
1172
|
+
* the serialized transition. A decision at or after that deadline (input.now >=
|
|
1173
|
+
* approvalExpiresAt) must never be applied: expire the row to failed with approvalExpiry
|
|
1174
|
+
* and no approvalDecision instead. The caller's decision.decidedAt does not extend it.
|
|
1175
|
+
* Each waiting row must settle exactly once across concurrent decisions and expiry sweeps;
|
|
1176
|
+
* a losing transition reports applied: false. With lifecycleEvent, the selected decided
|
|
1177
|
+
* or expired event/outbox writes and state change must commit in the same atomic unit
|
|
1178
|
+
* of work, or roll back together. Required when implementing parkApproval/expireDueApprovals.
|
|
1179
|
+
*/
|
|
1078
1180
|
beginApprovalDecision(input: BeginApprovalDecisionInput): Promise<ApprovalDecisionTransitionResult>;
|
|
1079
1181
|
}
|
|
1080
1182
|
/** Optional durable capabilities used when external-governance enrichment is configured. */
|
|
@@ -1124,7 +1226,7 @@ export interface ClaimActionInvocationsInput {
|
|
|
1124
1226
|
* - `claimActionInvocations` must never claim a running invocation without a
|
|
1125
1227
|
* lease, which is what a parked invocation is.
|
|
1126
1228
|
*/
|
|
1127
|
-
export type ActionInvocationPatch = Partial<Pick<ActionInvocationRecord, "finalizationCheckpoint" | "deferredBeforeEffectAttempt" | "status" | "result" | "error" | "authorizationReconciliation" | "adapterReconciliation" | "pendingStateTransition" | "pendingCompletion" | "externalCompletion">>;
|
|
1229
|
+
export type ActionInvocationPatch = Partial<Pick<ActionInvocationRecord, "approvalExpiresAt" | "approvalExpiry" | "approvalDecision" | "leaseOwner" | "leaseExpiresAt" | "leaseToken" | "attemptCount" | "finalizationCheckpoint" | "deferredBeforeEffectAttempt" | "status" | "result" | "error" | "authorizationReconciliation" | "adapterReconciliation" | "pendingStateTransition" | "pendingCompletion" | "externalCompletion">>;
|
|
1128
1230
|
export interface UpdateLeasedActionInvocationInput {
|
|
1129
1231
|
id: string;
|
|
1130
1232
|
tenantId: string;
|
|
@@ -1322,6 +1424,8 @@ export interface PlatformActionWorkerCycleResult {
|
|
|
1322
1424
|
failed: number;
|
|
1323
1425
|
/** Present when claimed agent work was durably parked instead of failing. */
|
|
1324
1426
|
waitingForApproval?: number;
|
|
1427
|
+
/** Due approval waits settled to failed during this cycle; present when positive. */
|
|
1428
|
+
expiredApprovals?: number;
|
|
1325
1429
|
/**
|
|
1326
1430
|
* Present only when > 0: claimed invocations whose execution threw a
|
|
1327
1431
|
* RetryableExecutionError (counted by error type, not by where it was thrown).
|
|
@@ -1446,7 +1550,11 @@ export interface PlatformHostOptions<TDb> {
|
|
|
1446
1550
|
shouldPublish?(event: AssetEventEnvelope): boolean;
|
|
1447
1551
|
};
|
|
1448
1552
|
/** Optional vertical-owned evaluator. When absent, agent behavior is unchanged. */
|
|
1449
|
-
hitlEvaluator?: AgentActionPolicyEvaluator
|
|
1553
|
+
hitlEvaluator?: (context: Parameters<AgentActionPolicyEvaluator>[0]) => HostHitlDecision | Promise<HostHitlDecision>;
|
|
1554
|
+
/** Positive integer milliseconds, used when the evaluator supplies no absolute deadline. */
|
|
1555
|
+
approvalDefaultTtlMs?: number;
|
|
1556
|
+
/** Atomic approval lifecycle events and outbox writes; defaults to false. */
|
|
1557
|
+
approvalLifecycleEvents?: boolean;
|
|
1450
1558
|
/** Durable evaluator/ruleset version recorded with every HITL decision. */
|
|
1451
1559
|
hitlPolicyVersion?: string;
|
|
1452
1560
|
/** Optional portable resolver; provider-specific implementations belong in integration packages. */
|
|
@@ -1560,7 +1668,15 @@ export interface PlatformHostOptions<TDb> {
|
|
|
1560
1668
|
*/
|
|
1561
1669
|
adapterDeadlineMs?: number;
|
|
1562
1670
|
}
|
|
1671
|
+
export interface ApprovalExpiryHost {
|
|
1672
|
+
expireDueApprovals(input?: ExpireDueApprovalsInput): Promise<{
|
|
1673
|
+
expired: string[];
|
|
1674
|
+
}>;
|
|
1675
|
+
}
|
|
1563
1676
|
export interface GovernedActionHost {
|
|
1677
|
+
expireDueApprovals?(input?: ExpireDueApprovalsInput): Promise<{
|
|
1678
|
+
expired: string[];
|
|
1679
|
+
}>;
|
|
1564
1680
|
submitAction(input: SubmitActionInput): Promise<SubmitActionResult>;
|
|
1565
1681
|
/** Whether this Host's registry contains an action with a non-empty staged-descendant allowlist. */
|
|
1566
1682
|
readonly hasStagedInvocationActions?: boolean;
|
|
@@ -1605,7 +1721,7 @@ export interface OutboxRequeueHost {
|
|
|
1605
1721
|
}
|
|
1606
1722
|
//#endregion
|
|
1607
1723
|
//#region src/host.d.ts
|
|
1608
|
-
export declare function createGovernedActionHost<TDb>(options: PlatformHostOptions<TDb>): GovernedActionHost & OutboxRequeueHost;
|
|
1724
|
+
export declare function createGovernedActionHost<TDb>(options: PlatformHostOptions<TDb>): GovernedActionHost & OutboxRequeueHost & ApprovalExpiryHost;
|
|
1609
1725
|
//#endregion
|
|
1610
1726
|
//#region src/memory-store.d.ts
|
|
1611
1727
|
export interface MemoryPlatformHostTransactionProvider<TDb> {
|
|
@@ -1615,6 +1731,8 @@ export interface MemoryPlatformHostTransactionProvider<TDb> {
|
|
|
1615
1731
|
export declare class MemoryPlatformHostStore<TDb> implements RecoverablePlatformHostStore<TDb>, ApprovalPlatformHostStore<TDb>, GovernancePlatformHostStore<TDb>, OutboxPlatformHostStore<TDb>, OutboxRequeuePlatformHostStore<TDb>, StagedInvocationPlatformHostStore<TDb> {
|
|
1616
1732
|
readonly db: TDb;
|
|
1617
1733
|
readonly transactionalOutbox: boolean;
|
|
1734
|
+
readonly transactionalApprovalLifecycle: boolean;
|
|
1735
|
+
private readonly approvalTransactionProvider;
|
|
1618
1736
|
readonly transactionalStagedInvocations: boolean;
|
|
1619
1737
|
transactionWithEvents?: <TResult>(run: (transaction: PlatformHostMutationTransaction<TDb>) => Promise<TResult>) => Promise<TResult>;
|
|
1620
1738
|
private adapterCommit;
|
|
@@ -1645,7 +1763,10 @@ export declare class MemoryPlatformHostStore<TDb> implements RecoverablePlatform
|
|
|
1645
1763
|
getActionInvocationByStagedOrigin(tenantId: string, spaceId: string, origin: StagedInvocationOrigin): Promise<ActionInvocationRecord | undefined>;
|
|
1646
1764
|
updateActionInvocation(id: string, tenantId: string, spaceId: string, patch: ActionInvocationPatch): Promise<void>;
|
|
1647
1765
|
recordHitlDecision(actionInvocationId: string, tenantId: string, spaceId: string, decision: HitlDecisionEvidence): Promise<ActionInvocationRecord>;
|
|
1766
|
+
private runApprovalTransaction;
|
|
1767
|
+
parkApproval(input: ParkApprovalInput): Promise<ApprovalDecisionTransitionResult>;
|
|
1648
1768
|
beginApprovalDecision(input: BeginApprovalDecisionInput): Promise<ApprovalDecisionTransitionResult>;
|
|
1769
|
+
expireDueApprovals(input: ExpireDueApprovalsStoreInput): Promise<ActionInvocationRecord[]>;
|
|
1649
1770
|
appendPolicyEvaluation(record: PolicyEvaluationRecord): Promise<void>;
|
|
1650
1771
|
recordMutationGovernance(actionInvocationId: string, tenantId: string, spaceId: string, context: Pick<ActionInvocationRecord, "mutationFootprint" | "executionPrincipal"> & {
|
|
1651
1772
|
footprint: NonNullable<ActionInvocationRecord["mutationFootprint"]>;
|
|
@@ -1832,6 +1953,7 @@ export declare class PostgresPlatformHostStore<TDb> implements RecoverablePlatfo
|
|
|
1832
1953
|
private readonly sql;
|
|
1833
1954
|
readonly transactionWithEvents?: AtomicMutationPlatformHostStore<TDb>["transactionWithEvents"];
|
|
1834
1955
|
readonly transactionalOutbox: boolean;
|
|
1956
|
+
readonly transactionalApprovalLifecycle: boolean;
|
|
1835
1957
|
readonly transactionalStagedInvocations: boolean;
|
|
1836
1958
|
constructor(db: TDb, sql: PlatformHostSqlClient, transactionProvider?: PostgresPlatformHostTransactionProvider<TDb>);
|
|
1837
1959
|
ensureSchema(): Promise<void>;
|
|
@@ -1843,6 +1965,8 @@ export declare class PostgresPlatformHostStore<TDb> implements RecoverablePlatfo
|
|
|
1843
1965
|
getActionInvocationByStagedOrigin(tenantId: string, spaceId: string, origin: StagedInvocationOrigin): Promise<ActionInvocationRecord | undefined>;
|
|
1844
1966
|
updateActionInvocation(id: string, tenantId: string, spaceId: string, patch: ActionInvocationPatch): Promise<void>;
|
|
1845
1967
|
recordHitlDecision(actionInvocationId: string, tenantId: string, spaceId: string, decision: HitlDecisionEvidence): Promise<ActionInvocationRecord>;
|
|
1968
|
+
parkApproval(input: ParkApprovalInput): Promise<ApprovalDecisionTransitionResult>;
|
|
1969
|
+
expireDueApprovals(input: ExpireDueApprovalsStoreInput): Promise<ActionInvocationRecord[]>;
|
|
1846
1970
|
beginApprovalDecision(input: BeginApprovalDecisionInput): Promise<ApprovalDecisionTransitionResult>;
|
|
1847
1971
|
appendPolicyEvaluation(record: PolicyEvaluationRecord): Promise<void>;
|
|
1848
1972
|
recordMutationGovernance(actionInvocationId: string, tenantId: string, spaceId: string, context: {
|