@fabricorg/platform-host 5.0.0 → 6.0.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/dist/index.d.ts CHANGED
@@ -1,4 +1,155 @@
1
1
  import { ActorType, ActionId, ActionStatus, AgentActionRoute, AgentActionRiskTier, MutationFootprint, ExecutionPrincipal, GovernanceRuntimeEvidence, PolicyOutcome, AssetEventEnvelope, ExecutionAttestation, ExternalReconciliation, PolicyObligation, PolicyObligationStatus, ModuleRegistry, ActionDefinition, AdapterImplementation, FabricRuntimeServices, AgentActionPolicyEvaluator, MutationGovernanceResolver, RuntimePolicyDefinition } from '@fabricorg/platform';
2
+ import { AssemblyLockfile } from '@fabricorg/assembly';
3
+
4
+ /** Version of the vendor-neutral health/readiness contract. */
5
+ declare const PLATFORM_HOST_HEALTH_CONTRACT_VERSION: 1;
6
+ /**
7
+ * Stable metric names. Adapters may translate these names to a vendor's
8
+ * naming convention, but applications should not derive names from labels.
9
+ */
10
+ declare const PLATFORM_HOST_METRIC_NAMES: {
11
+ readonly workerCyclesStarted: "fabric.platform.worker.cycles.started";
12
+ readonly workerCyclesCompleted: "fabric.platform.worker.cycles.completed";
13
+ readonly workerCyclesFailed: "fabric.platform.worker.cycles.failed";
14
+ readonly invocationSubmitted: "fabric.platform.invocation.submitted";
15
+ readonly invocationExecutionStarted: "fabric.platform.invocation.execution_started";
16
+ readonly invocationLeaseClaimed: "fabric.platform.invocation.lease_claimed";
17
+ readonly invocationCompleted: "fabric.platform.invocation.completed";
18
+ readonly invocationFailed: "fabric.platform.invocation.failed";
19
+ readonly invocationPolicyBlocked: "fabric.platform.invocation.policy_blocked";
20
+ readonly invocationValidationFailed: "fabric.platform.invocation.validation_failed";
21
+ readonly invocationApprovalWaited: "fabric.platform.invocation.approval_waited";
22
+ readonly invocationReconciliationRequired: "fabric.platform.invocation.reconciliation_required";
23
+ readonly outboxRelayCyclesStarted: "fabric.platform.outbox.relay_cycles.started";
24
+ readonly outboxRelayCyclesCompleted: "fabric.platform.outbox.relay_cycles.completed";
25
+ readonly outboxRelayCyclesFailed: "fabric.platform.outbox.relay_cycles.failed";
26
+ readonly outboxLeaseClaimed: "fabric.platform.outbox.lease_claimed";
27
+ readonly outboxPublished: "fabric.platform.outbox.published";
28
+ readonly outboxFailed: "fabric.platform.outbox.failed";
29
+ readonly outboxDeadLettered: "fabric.platform.outbox.dead_lettered";
30
+ readonly invocationBacklog: "fabric.platform.invocation.backlog";
31
+ readonly invocationRunning: "fabric.platform.invocation.running";
32
+ readonly invocationExpiredLeases: "fabric.platform.invocation.expired_leases";
33
+ readonly invocationApprovalWaits: "fabric.platform.invocation.approval_waits";
34
+ readonly invocationReconciliationRequiredGauge: "fabric.platform.invocation.reconciliation_required.count";
35
+ readonly outboxBacklog: "fabric.platform.outbox.backlog";
36
+ readonly outboxExpiredLeases: "fabric.platform.outbox.expired_leases";
37
+ readonly outboxDeadLetters: "fabric.platform.outbox.dead_letters";
38
+ };
39
+ type PlatformHostMetricName = (typeof PLATFORM_HOST_METRIC_NAMES)[keyof typeof PLATFORM_HOST_METRIC_NAMES];
40
+ type PlatformHostTelemetryEventName = "worker.cycle.started" | "worker.cycle.completed" | "worker.cycle.failed" | "invocation.submitted" | "invocation.execution_started" | "invocation.lease_claimed" | "invocation.completed" | "invocation.failed" | "invocation.policy_blocked" | "invocation.validation_failed" | "invocation.approval_waited" | "invocation.reconciliation_required" | "outbox.relay.started" | "outbox.relay.completed" | "outbox.relay.failed" | "outbox.lease_claimed" | "outbox.published" | "outbox.failed" | "outbox.dead_lettered";
41
+ type PlatformHostMetricType = "counter" | "gauge";
42
+ type PlatformHostTelemetryAttribute = string | number | boolean;
43
+ interface PlatformHostLifecycleTelemetry {
44
+ kind: "event";
45
+ name: PlatformHostTelemetryEventName;
46
+ metricName: PlatformHostMetricName;
47
+ metricType: "counter";
48
+ occurredAt: Date;
49
+ tenantId?: string;
50
+ spaceId?: string;
51
+ attributes?: Readonly<Record<string, PlatformHostTelemetryAttribute>>;
52
+ }
53
+ interface PlatformHostMetricTelemetry {
54
+ kind: "metric";
55
+ name: PlatformHostMetricName;
56
+ metricType: PlatformHostMetricType;
57
+ value: number;
58
+ observedAt: Date;
59
+ tenantId?: string;
60
+ spaceId?: string;
61
+ }
62
+ type PlatformHostTelemetryRecord = PlatformHostLifecycleTelemetry | PlatformHostMetricTelemetry;
63
+ type PlatformHostTelemetryHook = (record: PlatformHostTelemetryRecord) => void | Promise<void>;
64
+ /**
65
+ * A deliberately small sink contract. No OpenTelemetry, Prometheus, or
66
+ * vendor SDK is required by Platform Host.
67
+ */
68
+ type PlatformHostTelemetry = PlatformHostTelemetryHook | {
69
+ record: PlatformHostTelemetryHook;
70
+ };
71
+ type PlatformHostTelemetryInput = Omit<PlatformHostLifecycleTelemetry, "occurredAt" | "metricType"> & {
72
+ occurredAt?: Date;
73
+ } | Omit<PlatformHostMetricTelemetry, "observedAt"> & {
74
+ observedAt?: Date;
75
+ };
76
+ /**
77
+ * Telemetry is best effort and must never change governed mutation behavior.
78
+ * Promise-returning hooks are detached and rejected hooks are swallowed.
79
+ */
80
+ declare function emitPlatformHostTelemetry(telemetry: PlatformHostTelemetry | undefined, input: PlatformHostTelemetryInput): void;
81
+ interface PlatformHostHealthQuery {
82
+ tenantId?: string;
83
+ spaceId?: string;
84
+ now: Date;
85
+ }
86
+ interface PlatformHostHealthCounts {
87
+ invocationBacklog: number;
88
+ invocationRunning: number;
89
+ invocationExpiredLeases: number;
90
+ invocationApprovalWaits: number;
91
+ invocationReconciliationRequired: number;
92
+ outboxBacklog: number;
93
+ outboxExpiredLeases: number;
94
+ outboxDeadLetters: number;
95
+ }
96
+ interface PlatformHostWorkerHealthInput {
97
+ lastHeartbeatAt: Date;
98
+ staleAfterMs: number;
99
+ }
100
+ interface PlatformHostHealthOptions<TDb> {
101
+ store: PlatformHostStore<TDb>;
102
+ tenantId?: string;
103
+ spaceId?: string;
104
+ now?: () => Date;
105
+ /**
106
+ * Worker liveness is supplied by the deployment's supervisor or telemetry
107
+ * bridge. Only aggregate healthy/stale counts are returned.
108
+ */
109
+ workers?: readonly PlatformHostWorkerHealthInput[];
110
+ telemetry?: PlatformHostTelemetry;
111
+ }
112
+ interface PlatformHostHealthStore<TDb> extends RecoverablePlatformHostStore<TDb> {
113
+ getHealthCounts(input: PlatformHostHealthQuery): Promise<PlatformHostHealthCounts>;
114
+ }
115
+ type PlatformHostHealthStatus = "healthy" | "degraded" | "unhealthy";
116
+ interface PlatformHostHealthSnapshot {
117
+ contractVersion: typeof PLATFORM_HOST_HEALTH_CONTRACT_VERSION;
118
+ generatedAt: Date;
119
+ scope: {
120
+ tenantId?: string;
121
+ spaceId?: string;
122
+ };
123
+ dataAvailable: boolean;
124
+ status: PlatformHostHealthStatus;
125
+ readiness: {
126
+ ready: boolean;
127
+ reasonCodes: readonly PlatformHostReadinessReason[];
128
+ };
129
+ workers: {
130
+ reported: number;
131
+ healthy: number;
132
+ stale: number;
133
+ };
134
+ invocations: {
135
+ backlog: number;
136
+ running: number;
137
+ expiredLeases: number;
138
+ approvalWaits: number;
139
+ reconciliationRequired: number;
140
+ };
141
+ outbox: {
142
+ backlog: number;
143
+ expiredLeases: number;
144
+ deadLetters: number;
145
+ };
146
+ }
147
+ type PlatformHostReadinessReason = "health_source_unavailable" | "workers_stale" | "invocation_expired_leases" | "outbox_expired_leases" | "outbox_dead_letters" | "reconciliation_required";
148
+ /**
149
+ * Read tenant/space-scoped operational counts without returning invocation,
150
+ * actor, parameter, error, event, or adapter data.
151
+ */
152
+ declare function getPlatformHostHealthSnapshot<TDb>(options: PlatformHostHealthOptions<TDb>): Promise<PlatformHostHealthSnapshot>;
2
153
 
3
154
  /** Durable Host lifecycle generation, independent from the npm package version. */
4
155
  declare const PLATFORM_HOST_CONTRACT_VERSION: 2;
@@ -63,11 +214,15 @@ interface ActionInvocationRecord {
63
214
  authorizationBinding?: AuthorizationBinding;
64
215
  executionReason?: ActionExecutionReason;
65
216
  authorizationReconciliation?: AuthorizationReconciliationOutcome;
217
+ /** Durable evidence when an adapter returned an ambiguous outcome requiring reconciliation. */
218
+ adapterReconciliation?: AdapterReconciliationOutcome;
66
219
  /** Opaque, non-secret reference used to revalidate delegated execution authority. */
67
220
  authorizationBindingId?: string;
68
221
  attemptCount: number;
69
222
  leaseOwner?: string;
70
223
  leaseExpiresAt?: Date;
224
+ /** Monotonic claim generation used to reject writes from expired workers. */
225
+ leaseToken?: number;
71
226
  hitlRoute?: AgentActionRoute;
72
227
  hitlRiskTier?: AgentActionRiskTier;
73
228
  hitlReason?: string;
@@ -135,7 +290,18 @@ interface ExternalReconciliationRecord extends ExternalReconciliation {
135
290
  tenantId: string;
136
291
  spaceId: string;
137
292
  }
138
- type AdapterInvocationStatus = "running" | "succeeded" | "failed";
293
+ type AdapterInvocationStatus = "running" | "succeeded" | "failed" | "ambiguous";
294
+ interface AdapterReconciliationOutcome {
295
+ kind: "adapter_outcome_ambiguous";
296
+ adapterType: string;
297
+ operation: string;
298
+ vendor: string;
299
+ adapterInvocationId: string;
300
+ reason?: string;
301
+ /** Opaque, non-secret reference to external operation state for reconciliation. */
302
+ externalReference?: string;
303
+ message: string;
304
+ }
139
305
  interface AdapterInvocationRecord {
140
306
  id: string;
141
307
  actionInvocationId: string;
@@ -152,14 +318,19 @@ interface AdapterInvocationRecord {
152
318
  createdAt: Date;
153
319
  updatedAt: Date;
154
320
  }
155
- interface CreateActionInvocationInput extends Omit<ActionInvocationRecord, "createdAt" | "updatedAt" | "attemptCount" | "leaseOwner" | "leaseExpiresAt"> {
321
+ interface CreateActionInvocationInput extends Omit<ActionInvocationRecord, "createdAt" | "updatedAt" | "attemptCount" | "leaseOwner" | "leaseExpiresAt" | "leaseToken"> {
156
322
  }
157
323
  interface PlatformHostStore<TDb> {
158
324
  readonly db: TDb;
325
+ /**
326
+ * Run against the store's domain handle. This base seam does not promise a
327
+ * database transaction. Use `transactionWithEvents` when domain writes,
328
+ * canonical events, and invocation state must commit atomically.
329
+ */
159
330
  transaction<TResult>(run: (db: TDb) => Promise<TResult>): Promise<TResult>;
160
331
  createActionInvocation(input: CreateActionInvocationInput): Promise<ActionInvocationRecord>;
161
332
  getActionInvocation(id: string, tenantId: string, spaceId: string): Promise<ActionInvocationRecord | undefined>;
162
- updateActionInvocation(id: string, tenantId: string, spaceId: string, patch: Partial<Pick<ActionInvocationRecord, "status" | "result" | "error" | "authorizationReconciliation">>): Promise<void>;
333
+ updateActionInvocation(id: string, tenantId: string, spaceId: string, patch: Partial<Pick<ActionInvocationRecord, "status" | "result" | "error" | "authorizationReconciliation" | "adapterReconciliation">>): Promise<void>;
163
334
  appendPolicyEvaluation(record: PolicyEvaluationRecord): Promise<void>;
164
335
  createAdapterInvocation(record: AdapterInvocationRecord): Promise<void>;
165
336
  getAdapterInvocation(id: string): Promise<AdapterInvocationRecord | undefined>;
@@ -178,11 +349,23 @@ interface PlatformHostStore<TDb> {
178
349
  */
179
350
  interface PlatformHostMutationTransaction<TDb> {
180
351
  readonly db: TDb;
352
+ /**
353
+ * Read and lock an invocation until this transaction completes.
354
+ * Required by serialized saga parent lifecycle transitions.
355
+ */
356
+ getActionInvocationForUpdate?(id: string, tenantId: string, spaceId: string): Promise<ActionInvocationRecord | undefined>;
357
+ /**
358
+ * Read one event by its stable identity inside the transaction.
359
+ * Required by serialized saga parent lifecycle transitions.
360
+ */
361
+ getEvent?(id: string, tenantId: string, spaceId: string): Promise<AssetEventEnvelope | undefined>;
181
362
  appendEvent(event: AssetEventEnvelope): Promise<void>;
182
363
  appendEventWithOutbox?(event: AssetEventEnvelope, metadata: OutboxEventMetadata): Promise<void>;
183
364
  nextEventSequence(tenantId: string, spaceId: string): Promise<number>;
184
365
  listEvents(tenantId: string, spaceId: string): Promise<AssetEventEnvelope[]>;
185
- updateActionInvocation(id: string, tenantId: string, spaceId: string, patch: Partial<Pick<ActionInvocationRecord, "status" | "result" | "error" | "authorizationReconciliation">>): Promise<void>;
366
+ getEntityState?(tenantId: string, spaceId: string, entityType: string, entityId: string): Promise<string | undefined>;
367
+ updateActionInvocation(id: string, tenantId: string, spaceId: string, patch: Partial<Pick<ActionInvocationRecord, "status" | "result" | "error" | "authorizationReconciliation" | "adapterReconciliation">>): Promise<void>;
368
+ updateLeasedActionInvocation?(input: UpdateLeasedActionInvocationInput): Promise<boolean>;
186
369
  }
187
370
  type OutboxStatus = "pending" | "published" | "dead_letter";
188
371
  type EventPayloadClassification = "public" | "internal" | "confidential" | "restricted";
@@ -227,6 +410,7 @@ interface OutboxRecord {
227
410
  availableAt: Date;
228
411
  leaseOwner?: string;
229
412
  leaseExpiresAt?: Date;
413
+ leaseToken?: number;
230
414
  lastError?: string;
231
415
  createdAt: Date;
232
416
  publishedAt?: Date;
@@ -244,14 +428,22 @@ interface OutboxPlatformHostStore<TDb> extends PlatformHostStore<TDb> {
244
428
  readonly transactionalOutbox?: boolean;
245
429
  appendEventWithOutbox(event: AssetEventEnvelope, metadata: OutboxEventMetadata): Promise<void>;
246
430
  claimOutbox(input: ClaimOutboxInput): Promise<OutboxRecord[]>;
247
- markOutboxPublished(id: string, workerId: string, publishedAt: Date): Promise<void>;
431
+ markOutboxPublished(id: string, workerId: string, publishedAt: Date, leaseToken?: number): Promise<void>;
248
432
  markOutboxFailed(input: {
249
433
  id: string;
250
434
  workerId: string;
435
+ leaseToken?: number;
251
436
  error: string;
252
437
  availableAt: Date;
253
438
  deadLetter: boolean;
254
439
  }): Promise<void>;
440
+ renewOutboxLease(input: {
441
+ id: string;
442
+ workerId: string;
443
+ leaseToken: number;
444
+ leaseDurationMs: number;
445
+ now?: Date;
446
+ }): Promise<boolean>;
255
447
  listOutbox(input?: {
256
448
  tenantId?: string;
257
449
  spaceId?: string;
@@ -314,10 +506,30 @@ interface ClaimActionInvocationsInput {
314
506
  spaceId?: string;
315
507
  now?: Date;
316
508
  }
509
+ type ActionInvocationPatch = Partial<Pick<ActionInvocationRecord, "status" | "result" | "error" | "authorizationReconciliation" | "adapterReconciliation">>;
510
+ interface UpdateLeasedActionInvocationInput {
511
+ id: string;
512
+ tenantId: string;
513
+ spaceId: string;
514
+ workerId: string;
515
+ leaseToken: number;
516
+ patch: ActionInvocationPatch;
517
+ }
518
+ interface RenewActionInvocationLeaseInput {
519
+ id: string;
520
+ tenantId: string;
521
+ spaceId: string;
522
+ workerId: string;
523
+ leaseToken: number;
524
+ leaseDurationMs: number;
525
+ now?: Date;
526
+ }
317
527
  /** Store capabilities required by the durable polling worker and operator tooling. */
318
528
  interface RecoverablePlatformHostStore<TDb> extends PlatformHostStore<TDb> {
319
529
  listActionInvocations(input?: ListActionInvocationsInput): Promise<ActionInvocationRecord[]>;
320
530
  claimActionInvocations(input: ClaimActionInvocationsInput): Promise<ActionInvocationRecord[]>;
531
+ updateLeasedActionInvocation(input: UpdateLeasedActionInvocationInput): Promise<boolean>;
532
+ renewActionInvocationLease(input: RenewActionInvocationLeaseInput): Promise<boolean>;
321
533
  listEvents(tenantId: string, spaceId: string): Promise<AssetEventEnvelope[]>;
322
534
  }
323
535
  interface ActionAuthorizationInput {
@@ -359,6 +571,7 @@ interface PlatformHostAuthorization {
359
571
  }
360
572
  interface DispatchActionInput {
361
573
  actionInvocationId: string;
574
+ actionId: ActionId;
362
575
  tenantId: string;
363
576
  spaceId: string;
364
577
  workflowId: string;
@@ -381,7 +594,7 @@ interface SubmitActionInput {
381
594
  causationId?: string;
382
595
  provenance?: InvocationProvenance;
383
596
  executionReason?: Extract<KnownActionExecutionReason, "initial" | "offline_replay">;
384
- /** Stable logical command key. Reusing it returns the original invocation without re-dispatch. */
597
+ /** Stable logical command key. Reusing it returns the original invocation; a pending failed dispatch may retry its stable workflow ID. */
385
598
  idempotencyKey?: string;
386
599
  /** Opaque, non-secret authorization/admission reference persisted with the invocation. */
387
600
  authorizationBindingId?: string;
@@ -395,6 +608,7 @@ interface SubmitActionResult {
395
608
  result?: Record<string, unknown>;
396
609
  error?: string;
397
610
  reconciliation?: AuthorizationReconciliationOutcome;
611
+ adapterReconciliation?: AdapterReconciliationOutcome;
398
612
  /** Mirrors the action's declared consistency so a caller knows whether the result is settled. */
399
613
  consistency?: "authoritative-now" | "provisional-until-reconciled";
400
614
  hitlRoute?: AgentActionRoute;
@@ -406,6 +620,7 @@ interface ExecuteActionResult {
406
620
  result?: Record<string, unknown>;
407
621
  error?: string;
408
622
  reconciliation?: AuthorizationReconciliationOutcome;
623
+ adapterReconciliation?: AdapterReconciliationOutcome;
409
624
  /** Mirrors the action's declared consistency so a caller knows whether the result is settled. */
410
625
  consistency?: "authoritative-now" | "provisional-until-reconciled";
411
626
  hitlRoute?: AgentActionRoute;
@@ -414,6 +629,8 @@ interface ExecuteActionResult {
414
629
  interface ExecuteInvocationOptions {
415
630
  /** Required when executing a row already protected by a worker or approval-resume lease. */
416
631
  leaseOwner?: string;
632
+ /** Claim generation paired with leaseOwner; stale generations are rejected. */
633
+ leaseToken?: number;
417
634
  }
418
635
  interface PlatformActionWorkerOptions<TDb> {
419
636
  host: GovernedActionHost;
@@ -421,11 +638,13 @@ interface PlatformActionWorkerOptions<TDb> {
421
638
  workerId: string;
422
639
  batchSize?: number;
423
640
  leaseDurationMs?: number;
641
+ leaseRenewalIntervalMs?: number;
424
642
  pollIntervalMs?: number;
425
643
  tenantId?: string;
426
644
  spaceId?: string;
427
645
  signal?: AbortSignal;
428
646
  onError?: (error: unknown, invocation?: ActionInvocationRecord) => void;
647
+ telemetry?: PlatformHostTelemetry;
429
648
  }
430
649
  interface PlatformActionWorkerCycleResult {
431
650
  claimed: number;
@@ -438,7 +657,7 @@ interface PlatformHostOptions<TDb> {
438
657
  store: PlatformHostStore<TDb>;
439
658
  authorization: PlatformHostAuthorization;
440
659
  /** Preferred explicit catalog assembled from this runtime's Fabric modules. */
441
- registry?: Pick<ModuleRegistry<TDb>, "resolveAction" | "resolvePolicy" | "resolveStateMachine">;
660
+ registry?: Pick<ModuleRegistry<TDb>, "resolveAction" | "resolvePolicy" | "resolveStateMachine"> & Partial<Pick<ModuleRegistry<TDb>, "orderedModules">>;
442
661
  /** Resolve vertical- or runtime-local actions without mutating the process-wide registry. */
443
662
  resolveAction?: (actionId: ActionId) => ActionDefinition<TDb> | undefined;
444
663
  adapters?: readonly AdapterImplementation[];
@@ -488,6 +707,15 @@ interface PlatformHostOptions<TDb> {
488
707
  }) => Promise<ExecutionAttestation | undefined> | ExecutionAttestation | undefined;
489
708
  /** Package/provider/ruleset generations persisted with every newly created invocation. */
490
709
  runtimeEvidence?: Partial<GovernanceRuntimeEvidence>;
710
+ /**
711
+ * Trusted composition identity attached by the Host configuration, never
712
+ * accepted directly from submission input. Requires an explicit registry;
713
+ * its module namespaces and versions are checked against these identities.
714
+ */
715
+ composition?: {
716
+ assembly: AssemblyLockfile;
717
+ resolveInitiatingReleaseDigest?(input: SubmitActionInput): Promise<string | undefined> | string | undefined;
718
+ };
491
719
  /** Lease held while an approved invocation resumes; defaults to five minutes. */
492
720
  approvalResumeLeaseDurationMs?: number;
493
721
  /** Remove forbidden/sensitive fields before durable invocation persistence. */
@@ -504,6 +732,13 @@ interface PlatformHostOptions<TDb> {
504
732
  subjectId: string;
505
733
  } | undefined;
506
734
  now?: () => Date;
735
+ /** Vendor-neutral lifecycle and metric sink. Telemetry is best effort. */
736
+ telemetry?: PlatformHostTelemetry;
737
+ /**
738
+ * Epoch-millis deadline delivered to every adapter execution context.
739
+ * When omitted, no deadline is set and adapters receive no AbortSignal.
740
+ */
741
+ adapterDeadlineMs?: number;
507
742
  }
508
743
  interface GovernedActionHost {
509
744
  submitAction(input: SubmitActionInput): Promise<SubmitActionResult>;
@@ -537,7 +772,7 @@ declare class MemoryPlatformHostStore<TDb> implements RecoverablePlatformHostSto
537
772
  private runTransactionWithEvents;
538
773
  createActionInvocation(input: CreateActionInvocationInput): Promise<ActionInvocationRecord>;
539
774
  getActionInvocation(id: string, tenantId: string, spaceId: string): Promise<ActionInvocationRecord | undefined>;
540
- updateActionInvocation(id: string, tenantId: string, spaceId: string, patch: Partial<Pick<ActionInvocationRecord, "status" | "result" | "error" | "authorizationReconciliation">>): Promise<void>;
775
+ updateActionInvocation(id: string, tenantId: string, spaceId: string, patch: Partial<Pick<ActionInvocationRecord, "status" | "result" | "error" | "authorizationReconciliation" | "adapterReconciliation">>): Promise<void>;
541
776
  recordHitlDecision(actionInvocationId: string, tenantId: string, spaceId: string, decision: HitlDecisionEvidence): Promise<ActionInvocationRecord>;
542
777
  beginApprovalDecision(input: BeginApprovalDecisionInput): Promise<ApprovalDecisionTransitionResult>;
543
778
  appendPolicyEvaluation(record: PolicyEvaluationRecord): Promise<void>;
@@ -557,14 +792,22 @@ declare class MemoryPlatformHostStore<TDb> implements RecoverablePlatformHostSto
557
792
  appendEvent(event: AssetEventEnvelope): Promise<void>;
558
793
  appendEventWithOutbox(event: AssetEventEnvelope, metadata: OutboxEventMetadata): Promise<void>;
559
794
  claimOutbox(input: ClaimOutboxInput): Promise<OutboxRecord[]>;
560
- markOutboxPublished(id: string, workerId: string, publishedAt: Date): Promise<void>;
795
+ markOutboxPublished(id: string, workerId: string, publishedAt: Date, leaseToken?: number): Promise<void>;
561
796
  markOutboxFailed(input: {
562
797
  id: string;
563
798
  workerId: string;
799
+ leaseToken?: number;
564
800
  error: string;
565
801
  availableAt: Date;
566
802
  deadLetter: boolean;
567
803
  }): Promise<void>;
804
+ renewOutboxLease(input: {
805
+ id: string;
806
+ workerId: string;
807
+ leaseToken: number;
808
+ leaseDurationMs: number;
809
+ now?: Date;
810
+ }): Promise<boolean>;
568
811
  listOutbox(input?: {
569
812
  tenantId?: string;
570
813
  spaceId?: string;
@@ -574,23 +817,31 @@ declare class MemoryPlatformHostStore<TDb> implements RecoverablePlatformHostSto
574
817
  nextEventSequence(tenantId: string, spaceId: string): Promise<number>;
575
818
  getEntityState(tenantId: string, spaceId: string, entityType: string, entityId: string): Promise<string | undefined>;
576
819
  listActionInvocations(input?: ListActionInvocationsInput): Promise<ActionInvocationRecord[]>;
820
+ getHealthCounts(input: PlatformHostHealthQuery): Promise<PlatformHostHealthCounts>;
577
821
  claimActionInvocations(input: ClaimActionInvocationsInput): Promise<ActionInvocationRecord[]>;
822
+ updateLeasedActionInvocation(input: UpdateLeasedActionInvocationInput): Promise<boolean>;
823
+ renewActionInvocationLease(input: RenewActionInvocationLeaseInput): Promise<boolean>;
578
824
  listEvents(tenantId: string, spaceId: string): Promise<AssetEventEnvelope[]>;
579
825
  }
580
826
 
581
827
  declare function toEnterpriseEventEnvelope(event: AssetEventEnvelope, metadata: OutboxEventMetadata): EnterpriseEventEnvelope;
582
828
  interface EnterpriseEventPublisher {
583
- publish(event: EnterpriseEventEnvelope): Promise<void>;
829
+ publish(event: EnterpriseEventEnvelope, context?: {
830
+ signal: AbortSignal;
831
+ }): Promise<void>;
584
832
  }
585
833
  interface OutboxRelayOptions<TDb> {
586
834
  store: OutboxPlatformHostStore<TDb>;
587
835
  publisher: EnterpriseEventPublisher;
588
836
  workerId: string;
589
837
  leaseDurationMs?: number;
838
+ leaseRenewalIntervalMs?: number;
839
+ publishTimeoutMs?: number;
590
840
  batchSize?: number;
591
841
  maxAttempts?: number;
592
842
  retryDelayMs?: (attempt: number) => number;
593
843
  now?: () => Date;
844
+ telemetry?: PlatformHostTelemetry;
594
845
  }
595
846
  interface OutboxRelayResult {
596
847
  claimed: number;
@@ -633,7 +884,7 @@ declare class PostgresPlatformHostStore<TDb> implements RecoverablePlatformHostS
633
884
  transaction<TResult>(run: (db: TDb) => Promise<TResult>): Promise<TResult>;
634
885
  createActionInvocation(input: CreateActionInvocationInput): Promise<ActionInvocationRecord>;
635
886
  getActionInvocation(id: string, tenantId: string, spaceId: string): Promise<ActionInvocationRecord | undefined>;
636
- updateActionInvocation(id: string, tenantId: string, spaceId: string, patch: Partial<Pick<ActionInvocationRecord, "status" | "result" | "error" | "authorizationReconciliation">>): Promise<void>;
887
+ updateActionInvocation(id: string, tenantId: string, spaceId: string, patch: Partial<Pick<ActionInvocationRecord, "status" | "result" | "error" | "authorizationReconciliation" | "adapterReconciliation">>): Promise<void>;
637
888
  recordHitlDecision(actionInvocationId: string, tenantId: string, spaceId: string, decision: HitlDecisionEvidence): Promise<ActionInvocationRecord>;
638
889
  beginApprovalDecision(input: BeginApprovalDecisionInput): Promise<ApprovalDecisionTransitionResult>;
639
890
  appendPolicyEvaluation(record: PolicyEvaluationRecord): Promise<void>;
@@ -653,14 +904,22 @@ declare class PostgresPlatformHostStore<TDb> implements RecoverablePlatformHostS
653
904
  appendEvent(event: AssetEventEnvelope): Promise<void>;
654
905
  appendEventWithOutbox(event: AssetEventEnvelope, metadata: OutboxEventMetadata): Promise<void>;
655
906
  claimOutbox(input: ClaimOutboxInput): Promise<OutboxRecord[]>;
656
- markOutboxPublished(id: string, workerId: string, publishedAt: Date): Promise<void>;
907
+ markOutboxPublished(id: string, workerId: string, publishedAt: Date, leaseToken?: number): Promise<void>;
657
908
  markOutboxFailed(input: {
658
909
  id: string;
659
910
  workerId: string;
911
+ leaseToken?: number;
660
912
  error: string;
661
913
  availableAt: Date;
662
914
  deadLetter: boolean;
663
915
  }): Promise<void>;
916
+ renewOutboxLease(input: {
917
+ id: string;
918
+ workerId: string;
919
+ leaseToken: number;
920
+ leaseDurationMs: number;
921
+ now?: Date;
922
+ }): Promise<boolean>;
664
923
  listOutbox(input?: {
665
924
  tenantId?: string;
666
925
  spaceId?: string;
@@ -669,9 +928,26 @@ declare class PostgresPlatformHostStore<TDb> implements RecoverablePlatformHostS
669
928
  nextEventSequence(tenantId: string, spaceId: string): Promise<number>;
670
929
  getEntityState(tenantId: string, spaceId: string, entityType: string, entityId: string): Promise<string | undefined>;
671
930
  listActionInvocations(input?: ListActionInvocationsInput): Promise<ActionInvocationRecord[]>;
931
+ getHealthCounts(input: PlatformHostHealthQuery): Promise<PlatformHostHealthCounts>;
672
932
  claimActionInvocations(input: ClaimActionInvocationsInput): Promise<ActionInvocationRecord[]>;
933
+ updateLeasedActionInvocation(input: UpdateLeasedActionInvocationInput): Promise<boolean>;
934
+ renewActionInvocationLease(input: RenewActionInvocationLeaseInput): Promise<boolean>;
673
935
  listEvents(tenantId: string, spaceId: string): Promise<AssetEventEnvelope[]>;
936
+ getEvent(id: string, tenantId: string, spaceId: string): Promise<AssetEventEnvelope | undefined>;
937
+ }
938
+
939
+ interface PostgresMigration {
940
+ version: number;
941
+ name: string;
942
+ sql: string;
674
943
  }
944
+ /**
945
+ * Applies an immutable, ordered migration set in one PostgreSQL transaction.
946
+ *
947
+ * The transaction-scoped advisory lock serializes migrators. A previously
948
+ * applied version may be presented again only when its checksum is unchanged.
949
+ */
950
+ declare function applyPostgresMigrations(client: PlatformHostSqlClient, migrations: readonly PostgresMigration[]): Promise<void>;
675
951
 
676
952
  declare const PARAMETER_DIGEST_ALGORITHM: "fabric-canonical-json-sha256-v1";
677
953
  declare function canonicalJson(value: unknown): string;
@@ -687,4 +963,92 @@ declare function runPlatformActionWorkerCycle<TDb>(options: PlatformActionWorker
687
963
  /** Poll until aborted. Each iteration is bounded and waits without busy-spinning. */
688
964
  declare function runPlatformActionWorker<TDb>(options: PlatformActionWorkerOptions<TDb>): Promise<void>;
689
965
 
690
- export { type ActionApprovalDecision, type ActionAuthorizationInput, type ActionExecutionAuthorizationInput, type ActionExecutionReason, type ActionInvocationRecord, type AdapterInvocationRecord, type AdapterInvocationStatus, type ApprovalDecisionTransitionResult, type ApprovalPlatformHostStore, type AtomicMutationPlatformHostStore, type AuthorizationBinding, type AuthorizationGoverningMoment, type AuthorizationReconciliationOutcome, type BeginApprovalDecisionInput, type ClaimActionInvocationsInput, type ClaimOutboxInput, type CreateActionInvocationInput, type DispatchActionInput, type DispatchActionResult, type EnterpriseEventEnvelope, type EnterpriseEventPublisher, type EventPayloadClassification, type ExecuteActionResult, type ExecuteInvocationOptions, type ExecutionAttestationRecord, type ExternalReconciliationRecord, type GovernancePlatformHostStore, type GovernedActionHost, type HitlDecisionEvidence, type IdempotencyConflict, IdempotencyConflictError, type InvocationProvenance, type InvocationSource, type KnownActionExecutionReason, type ListActionInvocationsInput, MemoryPlatformHostStore, type MemoryPlatformHostTransactionProvider, type NamespacedAttributes, type OutboxEventMetadata, type OutboxPlatformHostStore, type OutboxRecord, type OutboxRelayOptions, type OutboxRelayResult, type OutboxStatus, PARAMETER_DIGEST_ALGORITHM, PLATFORM_HOST_CONTRACT_VERSION, type PendingAssetEvent, type PersistedActionApprovalDecision, type PlatformActionDispatcher, type PlatformActionWorkerCycleResult, type PlatformActionWorkerOptions, type PlatformHostAuthorization, type PlatformHostMutationTransaction, type PlatformHostOptions, type PlatformHostSqlClient, type PlatformHostSqlResult, type PlatformHostStore, type PolicyEvaluationRecord, type PolicyObligationRecord, PostgresPlatformHostStore, type PostgresPlatformHostTransactionContext, type PostgresPlatformHostTransactionProvider, type RecoverablePlatformHostStore, type SubmitActionInput, type SubmitActionResult, canonicalJson, cloneOutboxRecord, createGovernedActionHost, createStoreBackedActionDispatcher, digestParameters, runOutboxRelayCycle, runPlatformActionWorker, runPlatformActionWorkerCycle, toEnterpriseEventEnvelope };
966
+ interface HostSagaParentLifecycleIdentity {
967
+ /** Stable identity shared by every retry of the same lifecycle transition. */
968
+ lifecycleId?: string;
969
+ }
970
+ /**
971
+ * Durable record of a single step completing within a saga parent.
972
+ * Structurally compatible with {@link import("@fabricorg/platform-temporal").SagaParentProgressRecord}.
973
+ */
974
+ interface HostSagaParentProgressRecord {
975
+ stepId: string;
976
+ index: number;
977
+ total: number;
978
+ completedAt: string;
979
+ }
980
+ interface HostSagaParentProgressInput extends HostSagaParentLifecycleIdentity {
981
+ parentInvocationId: string;
982
+ tenantId: string;
983
+ spaceId: string;
984
+ progress: HostSagaParentProgressRecord;
985
+ }
986
+ interface HostSagaParentApprovalInput extends HostSagaParentLifecycleIdentity {
987
+ parentInvocationId: string;
988
+ tenantId: string;
989
+ spaceId: string;
990
+ stepId: string;
991
+ approvalId: string;
992
+ reason: string;
993
+ }
994
+ interface HostSagaParentCancellationInput extends HostSagaParentLifecycleIdentity {
995
+ parentInvocationId: string;
996
+ tenantId: string;
997
+ spaceId: string;
998
+ reason: string;
999
+ actorId: string;
1000
+ }
1001
+ interface HostSagaParentCompletionInput extends HostSagaParentLifecycleIdentity {
1002
+ parentInvocationId: string;
1003
+ tenantId: string;
1004
+ spaceId: string;
1005
+ result: Record<string, unknown>;
1006
+ }
1007
+ interface HostSagaParentFailureInput extends HostSagaParentLifecycleIdentity {
1008
+ parentInvocationId: string;
1009
+ tenantId: string;
1010
+ spaceId: string;
1011
+ error: string;
1012
+ compensation: HostCompensationRecord[];
1013
+ }
1014
+ interface HostCompensationRecord {
1015
+ stepId: string;
1016
+ actionId: string;
1017
+ error?: string;
1018
+ }
1019
+ /**
1020
+ * Durable saga parent lifecycle contract backed by a Platform Host store.
1021
+ *
1022
+ * Structurally compatible with {@link import("@fabricorg/platform-temporal").SagaParentLifecycle}
1023
+ * so an instance can be passed directly to
1024
+ * {@link import("@fabricorg/platform-temporal").createSagaParentActivities}.
1025
+ *
1026
+ * Every transition is durable: the parent invocation row is the authoritative
1027
+ * state, and lifecycle events are the audit trail. A worker that rolls over
1028
+ * mid-saga can create a fresh adapter pointing at the same store and observe
1029
+ * the persisted progress, approval park, cancellation, completion, or failure
1030
+ * without in-memory state.
1031
+ */
1032
+ interface HostSagaParentLifecycle {
1033
+ recordProgress(input: HostSagaParentProgressInput): Promise<void>;
1034
+ parkApproval(input: HostSagaParentApprovalInput): Promise<void>;
1035
+ cancel(input: HostSagaParentCancellationInput): Promise<void>;
1036
+ complete(input: HostSagaParentCompletionInput): Promise<void>;
1037
+ fail(input: HostSagaParentFailureInput): Promise<void>;
1038
+ }
1039
+ interface CreateDurableSagaParentLifecycleOptions<TDb> {
1040
+ store: PlatformHostStore<TDb>;
1041
+ /** Optional clock for deterministic tests. */
1042
+ now?: () => Date;
1043
+ }
1044
+ /**
1045
+ * Create a {@link HostSagaParentLifecycle} backed by a Platform Host store.
1046
+ *
1047
+ * The parent invocation must already exist in the store (created by
1048
+ * `submitAction` or `createActionInvocation`). Each method appends a typed
1049
+ * lifecycle event and transitions the parent invocation to the appropriate
1050
+ * status so a fresh worker can observe the persisted state after a rollover.
1051
+ */
1052
+ declare function createDurableSagaParentLifecycle<TDb>(options: CreateDurableSagaParentLifecycleOptions<TDb>): HostSagaParentLifecycle;
1053
+
1054
+ export { type ActionApprovalDecision, type ActionAuthorizationInput, type ActionExecutionAuthorizationInput, type ActionExecutionReason, type ActionInvocationPatch, type ActionInvocationRecord, type AdapterInvocationRecord, type AdapterInvocationStatus, type AdapterReconciliationOutcome, type ApprovalDecisionTransitionResult, type ApprovalPlatformHostStore, type AtomicMutationPlatformHostStore, type AuthorizationBinding, type AuthorizationGoverningMoment, type AuthorizationReconciliationOutcome, type BeginApprovalDecisionInput, type ClaimActionInvocationsInput, type ClaimOutboxInput, type CreateActionInvocationInput, type CreateDurableSagaParentLifecycleOptions, type DispatchActionInput, type DispatchActionResult, type EnterpriseEventEnvelope, type EnterpriseEventPublisher, type EventPayloadClassification, type ExecuteActionResult, type ExecuteInvocationOptions, type ExecutionAttestationRecord, type ExternalReconciliationRecord, type GovernancePlatformHostStore, type GovernedActionHost, type HitlDecisionEvidence, type HostCompensationRecord, type HostSagaParentApprovalInput, type HostSagaParentCancellationInput, type HostSagaParentCompletionInput, type HostSagaParentFailureInput, type HostSagaParentLifecycle, type HostSagaParentProgressInput, type HostSagaParentProgressRecord, type IdempotencyConflict, IdempotencyConflictError, type InvocationProvenance, type InvocationSource, type KnownActionExecutionReason, type ListActionInvocationsInput, MemoryPlatformHostStore, type MemoryPlatformHostTransactionProvider, type NamespacedAttributes, type OutboxEventMetadata, type OutboxPlatformHostStore, type OutboxRecord, type OutboxRelayOptions, type OutboxRelayResult, type OutboxStatus, PARAMETER_DIGEST_ALGORITHM, PLATFORM_HOST_CONTRACT_VERSION, PLATFORM_HOST_HEALTH_CONTRACT_VERSION, PLATFORM_HOST_METRIC_NAMES, type PendingAssetEvent, type PersistedActionApprovalDecision, type PlatformActionDispatcher, type PlatformActionWorkerCycleResult, type PlatformActionWorkerOptions, type PlatformHostAuthorization, type PlatformHostHealthCounts, type PlatformHostHealthOptions, type PlatformHostHealthQuery, type PlatformHostHealthSnapshot, type PlatformHostHealthStatus, type PlatformHostHealthStore, type PlatformHostLifecycleTelemetry, type PlatformHostMetricName, type PlatformHostMetricTelemetry, type PlatformHostMetricType, type PlatformHostMutationTransaction, type PlatformHostOptions, type PlatformHostReadinessReason, type PlatformHostSqlClient, type PlatformHostSqlResult, type PlatformHostStore, type PlatformHostTelemetry, type PlatformHostTelemetryAttribute, type PlatformHostTelemetryEventName, type PlatformHostTelemetryHook, type PlatformHostTelemetryInput, type PlatformHostTelemetryRecord, type PlatformHostWorkerHealthInput, type PolicyEvaluationRecord, type PolicyObligationRecord, type PostgresMigration, PostgresPlatformHostStore, type PostgresPlatformHostTransactionContext, type PostgresPlatformHostTransactionProvider, type RecoverablePlatformHostStore, type RenewActionInvocationLeaseInput, type SubmitActionInput, type SubmitActionResult, type UpdateLeasedActionInvocationInput, applyPostgresMigrations, canonicalJson, cloneOutboxRecord, createDurableSagaParentLifecycle, createGovernedActionHost, createStoreBackedActionDispatcher, digestParameters, emitPlatformHostTelemetry, getPlatformHostHealthSnapshot, runOutboxRelayCycle, runPlatformActionWorker, runPlatformActionWorkerCycle, toEnterpriseEventEnvelope };