@fabricorg/platform-host 4.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";
@@ -213,6 +396,8 @@ interface EnterpriseEventEnvelope {
213
396
  source: InvocationSource;
214
397
  auditAttributes?: NamespacedAttributes;
215
398
  };
399
+ /** Present only for events an action declaring provisional consistency emitted. */
400
+ consistency?: "authoritative-now" | "provisional-until-reconciled";
216
401
  payload: unknown;
217
402
  }
218
403
  interface OutboxRecord {
@@ -225,6 +410,7 @@ interface OutboxRecord {
225
410
  availableAt: Date;
226
411
  leaseOwner?: string;
227
412
  leaseExpiresAt?: Date;
413
+ leaseToken?: number;
228
414
  lastError?: string;
229
415
  createdAt: Date;
230
416
  publishedAt?: Date;
@@ -242,14 +428,22 @@ interface OutboxPlatformHostStore<TDb> extends PlatformHostStore<TDb> {
242
428
  readonly transactionalOutbox?: boolean;
243
429
  appendEventWithOutbox(event: AssetEventEnvelope, metadata: OutboxEventMetadata): Promise<void>;
244
430
  claimOutbox(input: ClaimOutboxInput): Promise<OutboxRecord[]>;
245
- markOutboxPublished(id: string, workerId: string, publishedAt: Date): Promise<void>;
431
+ markOutboxPublished(id: string, workerId: string, publishedAt: Date, leaseToken?: number): Promise<void>;
246
432
  markOutboxFailed(input: {
247
433
  id: string;
248
434
  workerId: string;
435
+ leaseToken?: number;
249
436
  error: string;
250
437
  availableAt: Date;
251
438
  deadLetter: boolean;
252
439
  }): Promise<void>;
440
+ renewOutboxLease(input: {
441
+ id: string;
442
+ workerId: string;
443
+ leaseToken: number;
444
+ leaseDurationMs: number;
445
+ now?: Date;
446
+ }): Promise<boolean>;
253
447
  listOutbox(input?: {
254
448
  tenantId?: string;
255
449
  spaceId?: string;
@@ -312,10 +506,30 @@ interface ClaimActionInvocationsInput {
312
506
  spaceId?: string;
313
507
  now?: Date;
314
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
+ }
315
527
  /** Store capabilities required by the durable polling worker and operator tooling. */
316
528
  interface RecoverablePlatformHostStore<TDb> extends PlatformHostStore<TDb> {
317
529
  listActionInvocations(input?: ListActionInvocationsInput): Promise<ActionInvocationRecord[]>;
318
530
  claimActionInvocations(input: ClaimActionInvocationsInput): Promise<ActionInvocationRecord[]>;
531
+ updateLeasedActionInvocation(input: UpdateLeasedActionInvocationInput): Promise<boolean>;
532
+ renewActionInvocationLease(input: RenewActionInvocationLeaseInput): Promise<boolean>;
319
533
  listEvents(tenantId: string, spaceId: string): Promise<AssetEventEnvelope[]>;
320
534
  }
321
535
  interface ActionAuthorizationInput {
@@ -357,6 +571,7 @@ interface PlatformHostAuthorization {
357
571
  }
358
572
  interface DispatchActionInput {
359
573
  actionInvocationId: string;
574
+ actionId: ActionId;
360
575
  tenantId: string;
361
576
  spaceId: string;
362
577
  workflowId: string;
@@ -379,7 +594,7 @@ interface SubmitActionInput {
379
594
  causationId?: string;
380
595
  provenance?: InvocationProvenance;
381
596
  executionReason?: Extract<KnownActionExecutionReason, "initial" | "offline_replay">;
382
- /** 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. */
383
598
  idempotencyKey?: string;
384
599
  /** Opaque, non-secret authorization/admission reference persisted with the invocation. */
385
600
  authorizationBindingId?: string;
@@ -393,6 +608,9 @@ interface SubmitActionResult {
393
608
  result?: Record<string, unknown>;
394
609
  error?: string;
395
610
  reconciliation?: AuthorizationReconciliationOutcome;
611
+ adapterReconciliation?: AdapterReconciliationOutcome;
612
+ /** Mirrors the action's declared consistency so a caller knows whether the result is settled. */
613
+ consistency?: "authoritative-now" | "provisional-until-reconciled";
396
614
  hitlRoute?: AgentActionRoute;
397
615
  hitlRiskTier?: AgentActionRiskTier;
398
616
  }
@@ -402,12 +620,17 @@ interface ExecuteActionResult {
402
620
  result?: Record<string, unknown>;
403
621
  error?: string;
404
622
  reconciliation?: AuthorizationReconciliationOutcome;
623
+ adapterReconciliation?: AdapterReconciliationOutcome;
624
+ /** Mirrors the action's declared consistency so a caller knows whether the result is settled. */
625
+ consistency?: "authoritative-now" | "provisional-until-reconciled";
405
626
  hitlRoute?: AgentActionRoute;
406
627
  hitlRiskTier?: AgentActionRiskTier;
407
628
  }
408
629
  interface ExecuteInvocationOptions {
409
630
  /** Required when executing a row already protected by a worker or approval-resume lease. */
410
631
  leaseOwner?: string;
632
+ /** Claim generation paired with leaseOwner; stale generations are rejected. */
633
+ leaseToken?: number;
411
634
  }
412
635
  interface PlatformActionWorkerOptions<TDb> {
413
636
  host: GovernedActionHost;
@@ -415,11 +638,13 @@ interface PlatformActionWorkerOptions<TDb> {
415
638
  workerId: string;
416
639
  batchSize?: number;
417
640
  leaseDurationMs?: number;
641
+ leaseRenewalIntervalMs?: number;
418
642
  pollIntervalMs?: number;
419
643
  tenantId?: string;
420
644
  spaceId?: string;
421
645
  signal?: AbortSignal;
422
646
  onError?: (error: unknown, invocation?: ActionInvocationRecord) => void;
647
+ telemetry?: PlatformHostTelemetry;
423
648
  }
424
649
  interface PlatformActionWorkerCycleResult {
425
650
  claimed: number;
@@ -432,7 +657,7 @@ interface PlatformHostOptions<TDb> {
432
657
  store: PlatformHostStore<TDb>;
433
658
  authorization: PlatformHostAuthorization;
434
659
  /** Preferred explicit catalog assembled from this runtime's Fabric modules. */
435
- registry?: Pick<ModuleRegistry<TDb>, "resolveAction" | "resolvePolicy" | "resolveStateMachine">;
660
+ registry?: Pick<ModuleRegistry<TDb>, "resolveAction" | "resolvePolicy" | "resolveStateMachine"> & Partial<Pick<ModuleRegistry<TDb>, "orderedModules">>;
436
661
  /** Resolve vertical- or runtime-local actions without mutating the process-wide registry. */
437
662
  resolveAction?: (actionId: ActionId) => ActionDefinition<TDb> | undefined;
438
663
  adapters?: readonly AdapterImplementation[];
@@ -482,6 +707,15 @@ interface PlatformHostOptions<TDb> {
482
707
  }) => Promise<ExecutionAttestation | undefined> | ExecutionAttestation | undefined;
483
708
  /** Package/provider/ruleset generations persisted with every newly created invocation. */
484
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
+ };
485
719
  /** Lease held while an approved invocation resumes; defaults to five minutes. */
486
720
  approvalResumeLeaseDurationMs?: number;
487
721
  /** Remove forbidden/sensitive fields before durable invocation persistence. */
@@ -498,6 +732,13 @@ interface PlatformHostOptions<TDb> {
498
732
  subjectId: string;
499
733
  } | undefined;
500
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;
501
742
  }
502
743
  interface GovernedActionHost {
503
744
  submitAction(input: SubmitActionInput): Promise<SubmitActionResult>;
@@ -531,7 +772,7 @@ declare class MemoryPlatformHostStore<TDb> implements RecoverablePlatformHostSto
531
772
  private runTransactionWithEvents;
532
773
  createActionInvocation(input: CreateActionInvocationInput): Promise<ActionInvocationRecord>;
533
774
  getActionInvocation(id: string, tenantId: string, spaceId: string): Promise<ActionInvocationRecord | undefined>;
534
- 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>;
535
776
  recordHitlDecision(actionInvocationId: string, tenantId: string, spaceId: string, decision: HitlDecisionEvidence): Promise<ActionInvocationRecord>;
536
777
  beginApprovalDecision(input: BeginApprovalDecisionInput): Promise<ApprovalDecisionTransitionResult>;
537
778
  appendPolicyEvaluation(record: PolicyEvaluationRecord): Promise<void>;
@@ -551,14 +792,22 @@ declare class MemoryPlatformHostStore<TDb> implements RecoverablePlatformHostSto
551
792
  appendEvent(event: AssetEventEnvelope): Promise<void>;
552
793
  appendEventWithOutbox(event: AssetEventEnvelope, metadata: OutboxEventMetadata): Promise<void>;
553
794
  claimOutbox(input: ClaimOutboxInput): Promise<OutboxRecord[]>;
554
- markOutboxPublished(id: string, workerId: string, publishedAt: Date): Promise<void>;
795
+ markOutboxPublished(id: string, workerId: string, publishedAt: Date, leaseToken?: number): Promise<void>;
555
796
  markOutboxFailed(input: {
556
797
  id: string;
557
798
  workerId: string;
799
+ leaseToken?: number;
558
800
  error: string;
559
801
  availableAt: Date;
560
802
  deadLetter: boolean;
561
803
  }): Promise<void>;
804
+ renewOutboxLease(input: {
805
+ id: string;
806
+ workerId: string;
807
+ leaseToken: number;
808
+ leaseDurationMs: number;
809
+ now?: Date;
810
+ }): Promise<boolean>;
562
811
  listOutbox(input?: {
563
812
  tenantId?: string;
564
813
  spaceId?: string;
@@ -568,23 +817,31 @@ declare class MemoryPlatformHostStore<TDb> implements RecoverablePlatformHostSto
568
817
  nextEventSequence(tenantId: string, spaceId: string): Promise<number>;
569
818
  getEntityState(tenantId: string, spaceId: string, entityType: string, entityId: string): Promise<string | undefined>;
570
819
  listActionInvocations(input?: ListActionInvocationsInput): Promise<ActionInvocationRecord[]>;
820
+ getHealthCounts(input: PlatformHostHealthQuery): Promise<PlatformHostHealthCounts>;
571
821
  claimActionInvocations(input: ClaimActionInvocationsInput): Promise<ActionInvocationRecord[]>;
822
+ updateLeasedActionInvocation(input: UpdateLeasedActionInvocationInput): Promise<boolean>;
823
+ renewActionInvocationLease(input: RenewActionInvocationLeaseInput): Promise<boolean>;
572
824
  listEvents(tenantId: string, spaceId: string): Promise<AssetEventEnvelope[]>;
573
825
  }
574
826
 
575
827
  declare function toEnterpriseEventEnvelope(event: AssetEventEnvelope, metadata: OutboxEventMetadata): EnterpriseEventEnvelope;
576
828
  interface EnterpriseEventPublisher {
577
- publish(event: EnterpriseEventEnvelope): Promise<void>;
829
+ publish(event: EnterpriseEventEnvelope, context?: {
830
+ signal: AbortSignal;
831
+ }): Promise<void>;
578
832
  }
579
833
  interface OutboxRelayOptions<TDb> {
580
834
  store: OutboxPlatformHostStore<TDb>;
581
835
  publisher: EnterpriseEventPublisher;
582
836
  workerId: string;
583
837
  leaseDurationMs?: number;
838
+ leaseRenewalIntervalMs?: number;
839
+ publishTimeoutMs?: number;
584
840
  batchSize?: number;
585
841
  maxAttempts?: number;
586
842
  retryDelayMs?: (attempt: number) => number;
587
843
  now?: () => Date;
844
+ telemetry?: PlatformHostTelemetry;
588
845
  }
589
846
  interface OutboxRelayResult {
590
847
  claimed: number;
@@ -627,7 +884,7 @@ declare class PostgresPlatformHostStore<TDb> implements RecoverablePlatformHostS
627
884
  transaction<TResult>(run: (db: TDb) => Promise<TResult>): Promise<TResult>;
628
885
  createActionInvocation(input: CreateActionInvocationInput): Promise<ActionInvocationRecord>;
629
886
  getActionInvocation(id: string, tenantId: string, spaceId: string): Promise<ActionInvocationRecord | undefined>;
630
- 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>;
631
888
  recordHitlDecision(actionInvocationId: string, tenantId: string, spaceId: string, decision: HitlDecisionEvidence): Promise<ActionInvocationRecord>;
632
889
  beginApprovalDecision(input: BeginApprovalDecisionInput): Promise<ApprovalDecisionTransitionResult>;
633
890
  appendPolicyEvaluation(record: PolicyEvaluationRecord): Promise<void>;
@@ -647,14 +904,22 @@ declare class PostgresPlatformHostStore<TDb> implements RecoverablePlatformHostS
647
904
  appendEvent(event: AssetEventEnvelope): Promise<void>;
648
905
  appendEventWithOutbox(event: AssetEventEnvelope, metadata: OutboxEventMetadata): Promise<void>;
649
906
  claimOutbox(input: ClaimOutboxInput): Promise<OutboxRecord[]>;
650
- markOutboxPublished(id: string, workerId: string, publishedAt: Date): Promise<void>;
907
+ markOutboxPublished(id: string, workerId: string, publishedAt: Date, leaseToken?: number): Promise<void>;
651
908
  markOutboxFailed(input: {
652
909
  id: string;
653
910
  workerId: string;
911
+ leaseToken?: number;
654
912
  error: string;
655
913
  availableAt: Date;
656
914
  deadLetter: boolean;
657
915
  }): Promise<void>;
916
+ renewOutboxLease(input: {
917
+ id: string;
918
+ workerId: string;
919
+ leaseToken: number;
920
+ leaseDurationMs: number;
921
+ now?: Date;
922
+ }): Promise<boolean>;
658
923
  listOutbox(input?: {
659
924
  tenantId?: string;
660
925
  spaceId?: string;
@@ -663,9 +928,26 @@ declare class PostgresPlatformHostStore<TDb> implements RecoverablePlatformHostS
663
928
  nextEventSequence(tenantId: string, spaceId: string): Promise<number>;
664
929
  getEntityState(tenantId: string, spaceId: string, entityType: string, entityId: string): Promise<string | undefined>;
665
930
  listActionInvocations(input?: ListActionInvocationsInput): Promise<ActionInvocationRecord[]>;
931
+ getHealthCounts(input: PlatformHostHealthQuery): Promise<PlatformHostHealthCounts>;
666
932
  claimActionInvocations(input: ClaimActionInvocationsInput): Promise<ActionInvocationRecord[]>;
933
+ updateLeasedActionInvocation(input: UpdateLeasedActionInvocationInput): Promise<boolean>;
934
+ renewActionInvocationLease(input: RenewActionInvocationLeaseInput): Promise<boolean>;
667
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;
668
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>;
669
951
 
670
952
  declare const PARAMETER_DIGEST_ALGORITHM: "fabric-canonical-json-sha256-v1";
671
953
  declare function canonicalJson(value: unknown): string;
@@ -681,4 +963,92 @@ declare function runPlatformActionWorkerCycle<TDb>(options: PlatformActionWorker
681
963
  /** Poll until aborted. Each iteration is bounded and waits without busy-spinning. */
682
964
  declare function runPlatformActionWorker<TDb>(options: PlatformActionWorkerOptions<TDb>): Promise<void>;
683
965
 
684
- 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 };