@fabricorg/platform-host 7.5.0 → 8.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.cts CHANGED
@@ -1,193 +1,194 @@
1
- import { ActorType, ActionId, ActionStatus, EvidencePacketReference, AgentActionRoute, AgentActionRiskTier, MutationFootprint, ExecutionPrincipal, GovernanceRuntimeEvidence, PolicyOutcome, AssetEventEnvelope, ExecutionAttestation, ExternalReconciliation, PolicyObligation, PolicyObligationStatus, ModuleRegistry, ActionDefinition, AdapterImplementation, AdapterCircuitBreakerProvider, FabricRuntimeServices, AgentActionPolicyEvaluator, MutationGovernanceResolver, RuntimePolicyDefinition } from '@fabricorg/platform';
2
- export { canonicalJson } from '@fabricorg/platform';
3
- import { AssemblyLockfile } from '@fabricorg/assembly';
4
-
1
+ import { ActionDefinition, ActionId, ActionStatus, ActorType, AdapterCircuitBreakerProvider, AdapterImplementation, AgentActionPolicyEvaluator, AgentActionRiskTier, AgentActionRoute, AssetEventEnvelope, EvidencePacketReference, ExecutionAttestation, ExecutionPrincipal, ExternalReconciliation, FabricRuntimeServices, GovernanceRuntimeEvidence, ModuleRegistry, MutationFootprint, MutationGovernanceResolver, PolicyObligation, PolicyObligationStatus, PolicyOutcome, RuntimePolicyDefinition, canonicalJson } from "@fabricorg/platform";
2
+ import { AssemblyLockfile } from "@fabricorg/assembly";
3
+ //#region src/observability.d.ts
5
4
  /** Version of the vendor-neutral health/readiness contract. */
6
- declare const PLATFORM_HOST_HEALTH_CONTRACT_VERSION: 1;
5
+ export declare const PLATFORM_HOST_HEALTH_CONTRACT_VERSION: 1;
7
6
  /**
8
7
  * Stable metric names. Adapters may translate these names to a vendor's
9
8
  * naming convention, but applications should not derive names from labels.
10
9
  */
11
- declare const PLATFORM_HOST_METRIC_NAMES: {
12
- readonly workerCyclesStarted: "fabric.platform.worker.cycles.started";
13
- readonly workerCyclesCompleted: "fabric.platform.worker.cycles.completed";
14
- readonly workerCyclesFailed: "fabric.platform.worker.cycles.failed";
15
- readonly invocationSubmitted: "fabric.platform.invocation.submitted";
16
- readonly invocationAdmissionRefused: "fabric.platform.invocation.admission_refused";
17
- readonly invocationExecutionStarted: "fabric.platform.invocation.execution_started";
18
- readonly invocationLeaseClaimed: "fabric.platform.invocation.lease_claimed";
19
- readonly invocationCompleted: "fabric.platform.invocation.completed";
20
- readonly invocationFailed: "fabric.platform.invocation.failed";
21
- readonly invocationPolicyBlocked: "fabric.platform.invocation.policy_blocked";
22
- readonly invocationValidationFailed: "fabric.platform.invocation.validation_failed";
23
- readonly invocationApprovalWaited: "fabric.platform.invocation.approval_waited";
24
- readonly invocationReconciliationRequired: "fabric.platform.invocation.reconciliation_required";
25
- readonly outboxRelayCyclesStarted: "fabric.platform.outbox.relay_cycles.started";
26
- readonly outboxRelayCyclesCompleted: "fabric.platform.outbox.relay_cycles.completed";
27
- readonly outboxRelayCyclesFailed: "fabric.platform.outbox.relay_cycles.failed";
28
- readonly outboxLeaseClaimed: "fabric.platform.outbox.lease_claimed";
29
- readonly outboxPublished: "fabric.platform.outbox.published";
30
- readonly outboxFailed: "fabric.platform.outbox.failed";
31
- readonly outboxDeadLettered: "fabric.platform.outbox.dead_lettered";
32
- readonly outboxRequeued: "fabric.platform.outbox.requeued";
33
- readonly outboxRequeueRefused: "fabric.platform.outbox.requeue_refused";
34
- readonly invocationBacklog: "fabric.platform.invocation.backlog";
35
- readonly invocationRunning: "fabric.platform.invocation.running";
36
- readonly invocationExpiredLeases: "fabric.platform.invocation.expired_leases";
37
- readonly invocationApprovalWaits: "fabric.platform.invocation.approval_waits";
38
- readonly invocationReconciliationRequiredGauge: "fabric.platform.invocation.reconciliation_required.count";
39
- readonly outboxBacklog: "fabric.platform.outbox.backlog";
40
- readonly outboxExpiredLeases: "fabric.platform.outbox.expired_leases";
41
- readonly outboxDeadLetters: "fabric.platform.outbox.dead_letters";
10
+ export 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 invocationAdmissionRefused: "fabric.platform.invocation.admission_refused";
16
+ readonly invocationExecutionStarted: "fabric.platform.invocation.execution_started";
17
+ readonly invocationLeaseClaimed: "fabric.platform.invocation.lease_claimed";
18
+ readonly invocationCompleted: "fabric.platform.invocation.completed";
19
+ readonly invocationFailed: "fabric.platform.invocation.failed";
20
+ readonly invocationPolicyBlocked: "fabric.platform.invocation.policy_blocked";
21
+ readonly invocationValidationFailed: "fabric.platform.invocation.validation_failed";
22
+ readonly invocationApprovalWaited: "fabric.platform.invocation.approval_waited";
23
+ readonly invocationReconciliationRequired: "fabric.platform.invocation.reconciliation_required";
24
+ readonly adapterEvidenceRefused: "fabric.platform.invocation.adapter_evidence_refused";
25
+ readonly outboxRelayCyclesStarted: "fabric.platform.outbox.relay_cycles.started";
26
+ readonly outboxRelayCyclesCompleted: "fabric.platform.outbox.relay_cycles.completed";
27
+ readonly outboxRelayCyclesFailed: "fabric.platform.outbox.relay_cycles.failed";
28
+ readonly outboxLeaseClaimed: "fabric.platform.outbox.lease_claimed";
29
+ readonly outboxPublished: "fabric.platform.outbox.published";
30
+ readonly outboxFailed: "fabric.platform.outbox.failed";
31
+ readonly outboxDeadLettered: "fabric.platform.outbox.dead_lettered";
32
+ readonly outboxRequeued: "fabric.platform.outbox.requeued";
33
+ readonly outboxRequeueRefused: "fabric.platform.outbox.requeue_refused";
34
+ readonly invocationBacklog: "fabric.platform.invocation.backlog";
35
+ readonly invocationRunning: "fabric.platform.invocation.running";
36
+ readonly invocationExpiredLeases: "fabric.platform.invocation.expired_leases";
37
+ readonly invocationApprovalWaits: "fabric.platform.invocation.approval_waits";
38
+ readonly invocationReconciliationRequiredGauge: "fabric.platform.invocation.reconciliation_required.count";
39
+ readonly outboxBacklog: "fabric.platform.outbox.backlog";
40
+ readonly outboxExpiredLeases: "fabric.platform.outbox.expired_leases";
41
+ readonly outboxDeadLetters: "fabric.platform.outbox.dead_letters";
42
42
  };
43
- type PlatformHostMetricName = (typeof PLATFORM_HOST_METRIC_NAMES)[keyof typeof PLATFORM_HOST_METRIC_NAMES];
44
- type PlatformHostTelemetryEventName = "worker.cycle.started" | "worker.cycle.completed" | "worker.cycle.failed" | "invocation.submitted" | "invocation.admission_refused" | "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" | "outbox.requeued" | "outbox.requeue_refused";
45
- type PlatformHostMetricType = "counter" | "gauge";
46
- type PlatformHostTelemetryAttribute = string | number | boolean;
47
- interface PlatformHostLifecycleTelemetry {
48
- kind: "event";
49
- name: PlatformHostTelemetryEventName;
50
- metricName: PlatformHostMetricName;
51
- metricType: "counter";
52
- occurredAt: Date;
53
- tenantId?: string;
54
- spaceId?: string;
55
- attributes?: Readonly<Record<string, PlatformHostTelemetryAttribute>>;
56
- }
57
- interface PlatformHostMetricTelemetry {
58
- kind: "metric";
59
- name: PlatformHostMetricName;
60
- metricType: PlatformHostMetricType;
61
- value: number;
62
- observedAt: Date;
63
- tenantId?: string;
64
- spaceId?: string;
65
- }
66
- type PlatformHostTelemetryRecord = PlatformHostLifecycleTelemetry | PlatformHostMetricTelemetry;
67
- type PlatformHostTelemetryHook = (record: PlatformHostTelemetryRecord) => void | Promise<void>;
43
+ export type PlatformHostMetricName = (typeof PLATFORM_HOST_METRIC_NAMES)[keyof typeof PLATFORM_HOST_METRIC_NAMES];
44
+ export type PlatformHostTelemetryEventName = "worker.cycle.started" | "worker.cycle.completed" | "worker.cycle.failed" | "invocation.submitted" | "invocation.admission_refused" | "invocation.execution_started" | "invocation.lease_claimed" | "invocation.completed" | "invocation.failed" | "invocation.policy_blocked" | "invocation.validation_failed" | "invocation.approval_waited" | "invocation.reconciliation_required" | "invocation.adapter_evidence_refused" | "outbox.relay.started" | "outbox.relay.completed" | "outbox.relay.failed" | "outbox.lease_claimed" | "outbox.published" | "outbox.failed" | "outbox.dead_lettered" | "outbox.requeued" | "outbox.requeue_refused";
45
+ export type PlatformHostMetricType = "counter" | "gauge";
46
+ export type PlatformHostTelemetryAttribute = string | number | boolean;
47
+ export interface PlatformHostLifecycleTelemetry {
48
+ kind: "event";
49
+ name: PlatformHostTelemetryEventName;
50
+ metricName: PlatformHostMetricName;
51
+ metricType: "counter";
52
+ occurredAt: Date;
53
+ tenantId?: string;
54
+ spaceId?: string;
55
+ attributes?: Readonly<Record<string, PlatformHostTelemetryAttribute>>;
56
+ }
57
+ export interface PlatformHostMetricTelemetry {
58
+ kind: "metric";
59
+ name: PlatformHostMetricName;
60
+ metricType: PlatformHostMetricType;
61
+ value: number;
62
+ observedAt: Date;
63
+ tenantId?: string;
64
+ spaceId?: string;
65
+ }
66
+ export type PlatformHostTelemetryRecord = PlatformHostLifecycleTelemetry | PlatformHostMetricTelemetry;
67
+ export type PlatformHostTelemetryHook = (record: PlatformHostTelemetryRecord) => void | Promise<void>;
68
68
  /**
69
69
  * A deliberately small sink contract. No OpenTelemetry, Prometheus, or
70
70
  * vendor SDK is required by Platform Host.
71
71
  */
72
- type PlatformHostTelemetry = PlatformHostTelemetryHook | {
73
- record: PlatformHostTelemetryHook;
72
+ export type PlatformHostTelemetry = PlatformHostTelemetryHook | {
73
+ record: PlatformHostTelemetryHook;
74
74
  };
75
- type PlatformHostTelemetryInput = Omit<PlatformHostLifecycleTelemetry, "occurredAt" | "metricType"> & {
76
- occurredAt?: Date;
75
+ export type PlatformHostTelemetryInput = Omit<PlatformHostLifecycleTelemetry, "occurredAt" | "metricType"> & {
76
+ occurredAt?: Date;
77
77
  } | Omit<PlatformHostMetricTelemetry, "observedAt"> & {
78
- observedAt?: Date;
78
+ observedAt?: Date;
79
79
  };
80
80
  /**
81
81
  * Telemetry is best effort and must never change governed mutation behavior.
82
82
  * Promise-returning hooks are detached and rejected hooks are swallowed.
83
83
  */
84
- declare function emitPlatformHostTelemetry(telemetry: PlatformHostTelemetry | undefined, input: PlatformHostTelemetryInput): void;
85
- interface PlatformHostHealthQuery {
84
+ export declare function emitPlatformHostTelemetry(telemetry: PlatformHostTelemetry | undefined, input: PlatformHostTelemetryInput): void;
85
+ export interface PlatformHostHealthQuery {
86
+ tenantId?: string;
87
+ spaceId?: string;
88
+ now: Date;
89
+ }
90
+ export interface PlatformHostHealthCounts {
91
+ invocationBacklog: number;
92
+ invocationRunning: number;
93
+ invocationExpiredLeases: number;
94
+ invocationApprovalWaits: number;
95
+ invocationReconciliationRequired: number;
96
+ outboxBacklog: number;
97
+ outboxExpiredLeases: number;
98
+ outboxDeadLetters: number;
99
+ }
100
+ export interface PlatformHostWorkerHealthInput {
101
+ lastHeartbeatAt: Date;
102
+ staleAfterMs: number;
103
+ }
104
+ export interface PlatformHostHealthOptions<TDb> {
105
+ store: PlatformHostStore<TDb>;
106
+ tenantId?: string;
107
+ spaceId?: string;
108
+ now?: () => Date;
109
+ /**
110
+ * Worker liveness is supplied by the deployment's supervisor or telemetry
111
+ * bridge. Only aggregate healthy/stale counts are returned.
112
+ */
113
+ workers?: readonly PlatformHostWorkerHealthInput[];
114
+ telemetry?: PlatformHostTelemetry;
115
+ }
116
+ export interface PlatformHostHealthStore<TDb> extends RecoverablePlatformHostStore<TDb> {
117
+ getHealthCounts(input: PlatformHostHealthQuery): Promise<PlatformHostHealthCounts>;
118
+ }
119
+ export type PlatformHostHealthStatus = "healthy" | "degraded" | "unhealthy";
120
+ export interface PlatformHostHealthSnapshot {
121
+ contractVersion: typeof PLATFORM_HOST_HEALTH_CONTRACT_VERSION;
122
+ generatedAt: Date;
123
+ scope: {
86
124
  tenantId?: string;
87
125
  spaceId?: string;
88
- now: Date;
89
- }
90
- interface PlatformHostHealthCounts {
91
- invocationBacklog: number;
92
- invocationRunning: number;
93
- invocationExpiredLeases: number;
94
- invocationApprovalWaits: number;
95
- invocationReconciliationRequired: number;
96
- outboxBacklog: number;
97
- outboxExpiredLeases: number;
98
- outboxDeadLetters: number;
99
- }
100
- interface PlatformHostWorkerHealthInput {
101
- lastHeartbeatAt: Date;
102
- staleAfterMs: number;
103
- }
104
- interface PlatformHostHealthOptions<TDb> {
105
- store: PlatformHostStore<TDb>;
106
- tenantId?: string;
107
- spaceId?: string;
108
- now?: () => Date;
109
- /**
110
- * Worker liveness is supplied by the deployment's supervisor or telemetry
111
- * bridge. Only aggregate healthy/stale counts are returned.
112
- */
113
- workers?: readonly PlatformHostWorkerHealthInput[];
114
- telemetry?: PlatformHostTelemetry;
115
- }
116
- interface PlatformHostHealthStore<TDb> extends RecoverablePlatformHostStore<TDb> {
117
- getHealthCounts(input: PlatformHostHealthQuery): Promise<PlatformHostHealthCounts>;
118
- }
119
- type PlatformHostHealthStatus = "healthy" | "degraded" | "unhealthy";
120
- interface PlatformHostHealthSnapshot {
121
- contractVersion: typeof PLATFORM_HOST_HEALTH_CONTRACT_VERSION;
122
- generatedAt: Date;
123
- scope: {
124
- tenantId?: string;
125
- spaceId?: string;
126
- };
127
- dataAvailable: boolean;
128
- status: PlatformHostHealthStatus;
129
- readiness: {
130
- ready: boolean;
131
- reasonCodes: readonly PlatformHostReadinessReason[];
132
- };
133
- workers: {
134
- reported: number;
135
- healthy: number;
136
- stale: number;
137
- };
138
- invocations: {
139
- backlog: number;
140
- running: number;
141
- expiredLeases: number;
142
- approvalWaits: number;
143
- reconciliationRequired: number;
144
- };
145
- outbox: {
146
- backlog: number;
147
- expiredLeases: number;
148
- deadLetters: number;
149
- };
150
- }
151
- type PlatformHostReadinessReason = "health_source_unavailable" | "workers_stale" | "invocation_expired_leases" | "outbox_expired_leases" | "outbox_dead_letters" | "reconciliation_required";
126
+ };
127
+ dataAvailable: boolean;
128
+ status: PlatformHostHealthStatus;
129
+ readiness: {
130
+ ready: boolean;
131
+ reasonCodes: readonly PlatformHostReadinessReason[];
132
+ };
133
+ workers: {
134
+ reported: number;
135
+ healthy: number;
136
+ stale: number;
137
+ };
138
+ invocations: {
139
+ backlog: number;
140
+ running: number;
141
+ expiredLeases: number;
142
+ approvalWaits: number;
143
+ reconciliationRequired: number;
144
+ };
145
+ outbox: {
146
+ backlog: number;
147
+ expiredLeases: number;
148
+ deadLetters: number;
149
+ };
150
+ }
151
+ export type PlatformHostReadinessReason = "health_source_unavailable" | "workers_stale" | "invocation_expired_leases" | "outbox_expired_leases" | "outbox_dead_letters" | "reconciliation_required";
152
152
  /**
153
153
  * Read tenant/space-scoped operational counts without returning invocation,
154
154
  * actor, parameter, error, event, or adapter data.
155
155
  */
156
- declare function getPlatformHostHealthSnapshot<TDb>(options: PlatformHostHealthOptions<TDb>): Promise<PlatformHostHealthSnapshot>;
157
-
156
+ export declare function getPlatformHostHealthSnapshot<TDb>(options: PlatformHostHealthOptions<TDb>): Promise<PlatformHostHealthSnapshot>;
157
+ //#endregion
158
+ //#region src/types.d.ts
158
159
  /** Durable Host lifecycle generation, independent from the npm package version. */
159
- declare const PLATFORM_HOST_CONTRACT_VERSION: 2;
160
- type InvocationSource = "ui" | "api" | "agent" | "worker" | "system" | (string & {});
161
- type NamespacedAttributes = Record<string, string>;
162
- interface InvocationProvenance {
163
- source: InvocationSource;
164
- correlationId: string;
165
- causationId?: string;
166
- traceAttributes?: NamespacedAttributes;
167
- auditAttributes?: NamespacedAttributes;
168
- }
169
- type AuthorizationGoverningMoment = "capture" | "execution" | "both";
170
- interface AuthorizationBinding {
171
- id: string;
172
- tenantId: string;
173
- actorId: string;
174
- actionId: string;
175
- parameterDigest: string;
176
- resourceScope?: string;
177
- capturedAt: string;
178
- expiresAt?: string;
179
- governingMoment: AuthorizationGoverningMoment;
180
- }
181
- interface IdempotencyConflict {
182
- code: "IDEMPOTENCY_CONFLICT";
183
- idempotencyKey: string;
184
- existingInvocationId: string;
185
- reasons: Array<"actor" | "authority_binding" | "action_version" | "parameters">;
186
- }
187
- declare class IdempotencyConflictError extends Error {
188
- readonly conflict: IdempotencyConflict;
189
- readonly code: "IDEMPOTENCY_CONFLICT";
190
- constructor(conflict: IdempotencyConflict);
160
+ export declare const PLATFORM_HOST_CONTRACT_VERSION: 2;
161
+ export type InvocationSource = "ui" | "api" | "agent" | "worker" | "system" | (string & {});
162
+ export type NamespacedAttributes = Record<string, string>;
163
+ export interface InvocationProvenance {
164
+ source: InvocationSource;
165
+ correlationId: string;
166
+ causationId?: string;
167
+ traceAttributes?: NamespacedAttributes;
168
+ auditAttributes?: NamespacedAttributes;
169
+ }
170
+ export type AuthorizationGoverningMoment = "capture" | "execution" | "both";
171
+ export interface AuthorizationBinding {
172
+ id: string;
173
+ tenantId: string;
174
+ actorId: string;
175
+ actionId: string;
176
+ parameterDigest: string;
177
+ resourceScope?: string;
178
+ capturedAt: string;
179
+ expiresAt?: string;
180
+ governingMoment: AuthorizationGoverningMoment;
181
+ }
182
+ export interface IdempotencyConflict {
183
+ code: "IDEMPOTENCY_CONFLICT";
184
+ idempotencyKey: string;
185
+ existingInvocationId: string;
186
+ reasons: Array<"actor" | "authority_binding" | "action_version" | "parameters">;
187
+ }
188
+ export declare class IdempotencyConflictError extends Error {
189
+ readonly conflict: IdempotencyConflict;
190
+ readonly code: "IDEMPOTENCY_CONFLICT";
191
+ constructor(conflict: IdempotencyConflict);
191
192
  }
192
193
  /**
193
194
  * Why `submitAction` did not admit a submission of an action that declares
@@ -199,7 +200,7 @@ declare class IdempotencyConflictError extends Error {
199
200
  * JSON-data object Host could copy at submission (a Proxy, a function, a
200
201
  * Date, a typed array or SharedArrayBuffer, a cycle, a getter that throws).
201
202
  */
202
- type ActionAdmissionRefusal = "refused" | "failed" | "timed_out" | "invalid_decision" | "invalid_parameters";
203
+ export type ActionAdmissionRefusal = "refused" | "failed" | "timed_out" | "invalid_decision" | "invalid_parameters";
203
204
  /**
204
205
  * Thrown by `submitAction` when a declared admission check did not admit the
205
206
  * submission. Host wrote nothing for it: no invocation, idempotency key,
@@ -207,17 +208,17 @@ type ActionAdmissionRefusal = "refused" | "failed" | "timed_out" | "invalid_deci
207
208
  * refusal and, for `refused`, the check's code; never a submitted value or
208
209
  * anything the check threw.
209
210
  */
210
- declare class ActionAdmissionError extends Error {
211
- readonly actionId: string;
212
- readonly refusal: ActionAdmissionRefusal;
213
- /** The check's own code, present only for `refused`. */
214
- readonly refusalCode?: string | undefined;
215
- readonly code: "ACTION_ADMISSION_REFUSED";
216
- constructor(actionId: string, refusal: ActionAdmissionRefusal,
217
- /** The check's own code, present only for `refused`. */
218
- refusalCode?: string | undefined);
219
- }
220
- type ExternalCompletionRefusal = "still_executing" | "not_found" | "not_awaiting" | "immediate_contract" | "reference_mismatch" | "provider_mismatch" | "invalid_completion" | "result_invalid" | "redaction_failed";
211
+ export declare class ActionAdmissionError extends Error {
212
+ readonly actionId: string;
213
+ readonly refusal: ActionAdmissionRefusal;
214
+ /** The check's own code, present only for `refused`. */
215
+ readonly refusalCode?: string | undefined;
216
+ readonly code: "ACTION_ADMISSION_REFUSED";
217
+ constructor(actionId: string, refusal: ActionAdmissionRefusal,
218
+ /** The check's own code, present only for `refused`. */
219
+ refusalCode?: string | undefined);
220
+ }
221
+ export type ExternalCompletionRefusal = "still_executing" | "not_found" | "not_awaiting" | "immediate_contract" | "reference_mismatch" | "provider_mismatch" | "invalid_completion" | "result_invalid" | "redaction_failed";
221
222
  /**
222
223
  * Why a completion was not applied, typed so a webhook handler can answer
223
224
  * the external system correctly: `retryable` means the invocation is still
@@ -227,147 +228,162 @@ type ExternalCompletionRefusal = "still_executing" | "not_found" | "not_awaiting
227
228
  * `redaction_failed` means completion result or error-text redaction failed before writes;
228
229
  * it is not retryable.
229
230
  */
230
- declare class ExternalCompletionError extends Error {
231
- readonly refusal: ExternalCompletionRefusal;
232
- readonly code: "EXTERNAL_COMPLETION_REFUSED";
233
- constructor(refusal: ExternalCompletionRefusal, message: string);
234
- get retryable(): boolean;
235
- }
236
- interface PendingAssetEvent {
237
- eventType: string;
238
- subjectType: string;
239
- subjectId: string;
240
- payload: unknown;
241
- eventSchemaVersion?: number;
242
- }
243
- interface ActionInvocationRecord {
244
- id: string;
245
- tenantId: string;
246
- spaceId: string;
247
- actionId: ActionId;
248
- actionVersion: number;
249
- actorId: string;
250
- actorType: ActorType;
251
- status: ActionStatus;
252
- parameters: Record<string, unknown>;
253
- result: Record<string, unknown>;
254
- correlationId: string;
255
- causationId?: string;
256
- idempotencyKey?: string;
257
- parameterDigest?: string;
258
- parameterDigestAlgorithm?: "fabric-canonical-json-sha256-v1";
259
- idempotencyActorId?: string;
260
- idempotencyAuthorizationBindingId?: string;
261
- provenance?: Omit<InvocationProvenance, "traceAttributes">;
262
- authorizationBinding?: AuthorizationBinding;
263
- executionReason?: ActionExecutionReason;
264
- authorizationReconciliation?: AuthorizationReconciliationOutcome;
265
- /** Durable evidence when an adapter returned an ambiguous outcome requiring reconciliation. */
266
- adapterReconciliation?: AdapterReconciliationOutcome;
267
- /**
268
- * A handoff the host is waiting on. While present the invocation is
269
- * `running` without a lease: it is not stuck, it is somebody else's turn,
270
- * and the recovery worker must not re-execute it.
271
- */
272
- pendingCompletion?: PendingExternalCompletion;
273
- /** The completion an external system delivered, kept so a repeat is recognised and a contradiction is caught. */
274
- externalCompletion?: RecordedExternalCompletion;
275
- /** Opaque, non-secret reference used to revalidate delegated execution authority. */
276
- authorizationBindingId?: string;
277
- attemptCount: number;
278
- leaseOwner?: string;
279
- leaseExpiresAt?: Date;
280
- /** Monotonic claim generation used to reject writes from expired workers. */
281
- leaseToken?: number;
282
- hitlRoute?: AgentActionRoute;
283
- hitlRiskTier?: AgentActionRiskTier;
284
- hitlReason?: string;
285
- hitlPolicyVersion?: string;
286
- approvalDecision?: PersistedActionApprovalDecision;
287
- mutationFootprint?: MutationFootprint;
288
- executionPrincipal?: ExecutionPrincipal;
289
- runtimeEvidence?: GovernanceRuntimeEvidence;
290
- /**
291
- * When `submitAction` admitted the submission through the action's
292
- * `admitSubmission` check, set on creation and never patched. Host refuses
293
- * to execute an invocation of an action that declares the check when this
294
- * is absent, and passes it to the handler as `ActionContext.admittedAt`.
295
- */
296
- admittedAt?: Date;
297
- error?: string;
298
- createdAt: Date;
299
- updatedAt: Date;
300
- }
301
- interface AuthorizationReconciliationOutcome {
302
- kind: "authorization_expired" | "authorization_denied" | "authorization_missing_capture_evidence";
303
- governingMoment: AuthorizationGoverningMoment;
304
- executionReason: ActionExecutionReason;
305
- authorizationBindingId?: string;
306
- provenance?: Omit<InvocationProvenance, "traceAttributes">;
307
- message: string;
308
- }
309
- interface HitlDecisionEvidence {
310
- route: AgentActionRoute;
311
- riskTier: AgentActionRiskTier;
312
- reason: string;
313
- policyVersion?: string;
314
- evaluatedAt: Date;
315
- }
316
- interface ActionApprovalDecision {
317
- approved: boolean;
318
- approverId: string;
319
- approverType: ActorType;
320
- reason?: string;
321
- editsReference?: string;
322
- decidedAt?: Date;
323
- }
324
- interface PersistedActionApprovalDecision extends Omit<ActionApprovalDecision, "decidedAt"> {
325
- decidedAt: Date;
326
- }
327
- interface PolicyEvaluationRecord {
328
- id: string;
329
- actionInvocationId: string;
330
- tenantId: string;
331
- spaceId: string;
332
- outcome: PolicyOutcome;
333
- createdAt: Date;
334
- }
335
- interface PolicyObligationRecord extends PolicyObligation {
336
- actionInvocationId: string;
337
- tenantId: string;
338
- spaceId: string;
339
- createdAt: Date;
340
- updatedAt: Date;
341
- }
342
- interface ExecutionAttestationRecord extends ExecutionAttestation {
343
- id: string;
344
- actionInvocationId: string;
345
- tenantId: string;
346
- spaceId: string;
347
- adapterInvocationId?: string;
348
- recordedAt: Date;
349
- }
350
- interface ExternalReconciliationRecord extends ExternalReconciliation {
351
- id: string;
352
- actionInvocationId: string;
353
- tenantId: string;
354
- spaceId: string;
355
- }
356
- interface PendingExternalCompletion {
357
- provider: string;
358
- adapterType: string;
359
- operation: string;
360
- adapterInvocationId: string;
361
- externalReference: string;
362
- acceptedAt: Date;
363
- /** Past this instant the host moves the invocation to reconciliation. */
364
- dueAt?: Date;
365
- /**
366
- * Set when the invocation finished executing and parked. A handoff is
367
- * recorded before the remaining steps run, so until this is set a
368
- * completion has nothing settled to settle into; it is asked to retry.
369
- */
370
- parkedAt?: Date;
231
+ export declare class ExternalCompletionError extends Error {
232
+ readonly refusal: ExternalCompletionRefusal;
233
+ readonly code: "EXTERNAL_COMPLETION_REFUSED";
234
+ constructor(refusal: ExternalCompletionRefusal, message: string);
235
+ get retryable(): boolean;
236
+ }
237
+ export interface PendingAssetEvent {
238
+ eventType: string;
239
+ subjectType: string;
240
+ subjectId: string;
241
+ payload: unknown;
242
+ eventSchemaVersion?: number;
243
+ }
244
+ export interface ActionInvocationRecord {
245
+ id: string;
246
+ tenantId: string;
247
+ spaceId: string;
248
+ actionId: ActionId;
249
+ actionVersion: number;
250
+ actorId: string;
251
+ actorType: ActorType;
252
+ status: ActionStatus;
253
+ parameters: Record<string, unknown>;
254
+ result: Record<string, unknown>;
255
+ correlationId: string;
256
+ causationId?: string;
257
+ idempotencyKey?: string;
258
+ parameterDigest?: string;
259
+ parameterDigestAlgorithm?: "fabric-canonical-json-sha256-v1";
260
+ idempotencyActorId?: string;
261
+ idempotencyAuthorizationBindingId?: string;
262
+ provenance?: Omit<InvocationProvenance, "traceAttributes">;
263
+ authorizationBinding?: AuthorizationBinding;
264
+ executionReason?: ActionExecutionReason;
265
+ authorizationReconciliation?: AuthorizationReconciliationOutcome;
266
+ /** Durable evidence when an adapter returned an ambiguous outcome requiring reconciliation. */
267
+ adapterReconciliation?: AdapterReconciliationOutcome;
268
+ /**
269
+ * Transition Host validated for an idempotent after_adapters action, saved
270
+ * after handler/result/event validation inside a mutation transaction, or before
271
+ * the handler otherwise. Supports recovered StateTransitioned emission and is
272
+ * retained as evidence after completion.
273
+ */
274
+ pendingStateTransition?: {
275
+ entityType: string;
276
+ entityId: string;
277
+ fromState: string;
278
+ toState: string;
279
+ };
280
+ /**
281
+ * A handoff the host is waiting on. While present the invocation is
282
+ * `running` without a lease: it is not stuck, it is somebody else's turn,
283
+ * and the recovery worker must not re-execute it.
284
+ */
285
+ pendingCompletion?: PendingExternalCompletion;
286
+ /** The completion an external system delivered, kept so a repeat is recognised and a contradiction is caught. */
287
+ externalCompletion?: RecordedExternalCompletion;
288
+ /** Opaque, non-secret reference used to revalidate delegated execution authority. */
289
+ authorizationBindingId?: string;
290
+ /** Worker claims including the first; approval acceptance sets a minimum of 1. */
291
+ attemptCount: number;
292
+ leaseOwner?: string;
293
+ leaseExpiresAt?: Date;
294
+ /** Monotonic claim generation used to reject writes from expired workers. */
295
+ leaseToken?: number;
296
+ hitlRoute?: AgentActionRoute;
297
+ hitlRiskTier?: AgentActionRiskTier;
298
+ hitlReason?: string;
299
+ hitlPolicyVersion?: string;
300
+ approvalDecision?: PersistedActionApprovalDecision;
301
+ mutationFootprint?: MutationFootprint;
302
+ executionPrincipal?: ExecutionPrincipal;
303
+ runtimeEvidence?: GovernanceRuntimeEvidence;
304
+ /**
305
+ * When `submitAction` admitted the submission through the action's
306
+ * `admitSubmission` check, set on creation and never patched. Host refuses
307
+ * to execute an invocation of an action that declares the check when this
308
+ * is absent, and passes it to the handler as `ActionContext.admittedAt`.
309
+ */
310
+ admittedAt?: Date;
311
+ error?: string;
312
+ createdAt: Date;
313
+ updatedAt: Date;
314
+ }
315
+ export interface AuthorizationReconciliationOutcome {
316
+ kind: "authorization_expired" | "authorization_denied" | "authorization_missing_capture_evidence";
317
+ governingMoment: AuthorizationGoverningMoment;
318
+ executionReason: ActionExecutionReason;
319
+ authorizationBindingId?: string;
320
+ provenance?: Omit<InvocationProvenance, "traceAttributes">;
321
+ message: string;
322
+ }
323
+ export interface HitlDecisionEvidence {
324
+ route: AgentActionRoute;
325
+ riskTier: AgentActionRiskTier;
326
+ reason: string;
327
+ policyVersion?: string;
328
+ evaluatedAt: Date;
329
+ }
330
+ export interface ActionApprovalDecision {
331
+ approved: boolean;
332
+ approverId: string;
333
+ approverType: ActorType;
334
+ reason?: string;
335
+ editsReference?: string;
336
+ decidedAt?: Date;
337
+ }
338
+ export interface PersistedActionApprovalDecision extends Omit<ActionApprovalDecision, "decidedAt"> {
339
+ decidedAt: Date;
340
+ }
341
+ export interface PolicyEvaluationRecord {
342
+ id: string;
343
+ actionInvocationId: string;
344
+ tenantId: string;
345
+ spaceId: string;
346
+ outcome: PolicyOutcome;
347
+ createdAt: Date;
348
+ }
349
+ export interface PolicyObligationRecord extends PolicyObligation {
350
+ actionInvocationId: string;
351
+ tenantId: string;
352
+ spaceId: string;
353
+ createdAt: Date;
354
+ updatedAt: Date;
355
+ }
356
+ export interface ExecutionAttestationRecord extends ExecutionAttestation {
357
+ id: string;
358
+ actionInvocationId: string;
359
+ tenantId: string;
360
+ spaceId: string;
361
+ adapterInvocationId?: string;
362
+ recordedAt: Date;
363
+ }
364
+ export interface ExternalReconciliationRecord extends ExternalReconciliation {
365
+ id: string;
366
+ actionInvocationId: string;
367
+ tenantId: string;
368
+ spaceId: string;
369
+ }
370
+ export interface PendingExternalCompletion {
371
+ provider: string;
372
+ adapterType: string;
373
+ operation: string;
374
+ adapterInvocationId: string;
375
+ externalReference: string;
376
+ acceptedAt: Date;
377
+ /** Past this instant the host moves the invocation to reconciliation. */
378
+ dueAt?: Date;
379
+ /**
380
+ * Set when the invocation finished executing and parked. A handoff is
381
+ * recorded before the remaining steps run, so until this is set a
382
+ * completion has nothing settled to settle into; it is asked to retry.
383
+ */
384
+ parkedAt?: Date;
385
+ /** Set with the overdue sweep verdict; does not prove execution parked. */
386
+ overdueAt?: Date;
371
387
  }
372
388
  /**
373
389
  * What an external system reports when it finishes work the host accepted.
@@ -377,109 +393,180 @@ interface PendingExternalCompletion {
377
393
  * refused, because completing the wrong invocation is worse than dropping a
378
394
  * callback.
379
395
  */
380
- interface ExternalCompletion {
381
- externalReference: string;
382
- outcome: "completed" | "failed";
383
- /** Merged over the handler's result on completion. */
384
- result?: Record<string, unknown>;
385
- error?: string;
386
- provider?: string;
387
- evidenceReferences?: EvidencePacketReference[];
388
- observedAt: Date | string;
389
- }
390
- interface RecordedExternalCompletion extends ExternalCompletion {
391
- recordedAt: Date;
392
- /**
393
- * Canonical digest of provider, reference, outcome, result, error, and
394
- * evidence. A repeat with the same digest is the same news; a repeat with
395
- * the same outcome and a different digest is changed evidence, and is a
396
- * contradiction like a flipped outcome. Observation time is left out,
397
- * since a redelivery legitimately carries a new one.
398
- */
399
- digest: string;
400
- }
401
- interface ReconcileOverdueCompletionsInput {
402
- tenantId?: string;
403
- spaceId?: string;
404
- limit?: number;
405
- now?: Date;
406
- }
407
- type AdapterInvocationStatus = "running" | "succeeded" | "failed" | "ambiguous";
408
- interface AdapterReconciliationOutcome {
409
- kind: "adapter_outcome_ambiguous";
410
- adapterType: string;
411
- operation: string;
412
- vendor: string;
413
- adapterInvocationId: string;
414
- reason?: string;
415
- /** Opaque, non-secret reference to external operation state for reconciliation. */
416
- externalReference?: string;
417
- message: string;
418
- }
419
- interface AdapterInvocationRecord {
420
- id: string;
421
- actionInvocationId: string;
422
- tenantId: string;
423
- spaceId: string;
424
- adapterType: string;
425
- operation: string;
426
- vendor: string;
427
- status: AdapterInvocationStatus;
428
- input: Record<string, unknown>;
429
- output?: Record<string, unknown>;
430
- error?: string;
431
- attempt: number;
432
- createdAt: Date;
433
- updatedAt: Date;
434
- }
435
- interface CreateActionInvocationInput extends Omit<ActionInvocationRecord, "createdAt" | "updatedAt" | "attemptCount" | "leaseOwner" | "leaseExpiresAt" | "leaseToken"> {
396
+ export interface ExternalCompletion {
397
+ externalReference: string;
398
+ outcome: "completed" | "failed";
399
+ /** Merged over the handler's result on completion. */
400
+ result?: Record<string, unknown>;
401
+ error?: string;
402
+ provider?: string;
403
+ evidenceReferences?: EvidencePacketReference[];
404
+ observedAt: Date | string;
405
+ }
406
+ export interface RecordedExternalCompletion extends ExternalCompletion {
407
+ recordedAt: Date;
408
+ /**
409
+ * Canonical digest of provider, reference, outcome, result, error, and
410
+ * evidence. A repeat with the same digest is the same news; a repeat with
411
+ * the same outcome and a different digest is changed evidence, and is a
412
+ * contradiction like a flipped outcome. Observation time is left out,
413
+ * since a redelivery legitimately carries a new one.
414
+ */
415
+ digest: string;
416
+ }
417
+ export interface ReconcileOverdueCompletionsInput {
418
+ tenantId?: string;
419
+ spaceId?: string;
420
+ limit?: number;
421
+ now?: Date;
422
+ }
423
+ export type AdapterInvocationStatus = "running" | "succeeded" | "failed" | "ambiguous";
424
+ export interface AdapterReconciliationOutcome {
425
+ kind: "adapter_outcome_ambiguous";
426
+ adapterType: string;
427
+ operation: string;
428
+ vendor: string;
429
+ adapterInvocationId: string;
430
+ reason?: string;
431
+ /** Opaque, non-secret reference to external operation state for reconciliation. */
432
+ externalReference?: string;
433
+ message: string;
434
+ }
435
+ export interface AdapterInvocationRecord {
436
+ id: string;
437
+ actionInvocationId: string;
438
+ tenantId: string;
439
+ spaceId: string;
440
+ adapterType: string;
441
+ operation: string;
442
+ vendor: string;
443
+ status: AdapterInvocationStatus;
444
+ input: Record<string, unknown>;
445
+ output?: Record<string, unknown>;
446
+ error?: string;
447
+ /** Redacted checkpoint for replaying an ambiguous settlement without another provider call. */
448
+ reconciliation?: AdapterReconciliationOutcome & {
449
+ /** Original event subject, stored only for settlement recovery. */
450
+ adapterEventSubject?: {
451
+ subjectType: string;
452
+ subjectId: string;
453
+ };
454
+ };
455
+ attempt: number;
456
+ createdAt: Date;
457
+ updatedAt: Date;
436
458
  }
459
+ export interface CreateActionInvocationInput extends Omit<ActionInvocationRecord, "createdAt" | "updatedAt" | "attemptCount" | "leaseOwner" | "leaseExpiresAt" | "leaseToken"> {}
437
460
  /** Scope of an adapter checkpoint within its owning action invocation. */
438
- interface AdapterInvocationScope {
439
- tenantId: string;
440
- spaceId: string;
461
+ export interface AdapterInvocationScope {
462
+ tenantId: string;
463
+ spaceId: string;
464
+ actionInvocationId: string;
465
+ }
466
+ /** Authority for an adapter mutation; verdict evidence uses exact status/error equality. */
467
+ export type AdapterInvocationWriteCondition = {
468
+ kind: "lease";
469
+ leaseOwner: string;
470
+ leaseToken: number;
471
+ } | {
472
+ kind: "verdict";
473
+ status: Exclude<ActionInvocationRecord["status"], "pending" | "running" | "waiting_for_approval">;
474
+ error?: string;
475
+ /** Absent requires no recorded completion; a digest requires that same completion. */
476
+ externalCompletionDigest?: string;
477
+ /** Captured handoff row; other adapter rows need only status/error and row-status fencing.
478
+ * Omit to retain the conservative completion check for adapter writes. Parent enrichment
479
+ * compares the completion digest regardless of this member. */
480
+ completionAdapterInvocationId?: string;
481
+ };
482
+ /** Conditionally enrich this execution's settled parent without changing its status. */
483
+ export interface UpdateSettledActionInvocationInput {
484
+ id: string;
485
+ tenantId: string;
486
+ spaceId: string;
487
+ condition: Extract<AdapterInvocationWriteCondition, {
488
+ kind: "verdict";
489
+ }>;
490
+ patch: Pick<ActionInvocationPatch, "error" | "adapterReconciliation">;
491
+ }
492
+ export type AdapterInvocationPatch = Partial<Pick<AdapterInvocationRecord, "status" | "output" | "error" | "attempt" | "updatedAt" | "reconciliation">>;
493
+ export interface AdapterInvocationWriteInput {
494
+ scope: AdapterInvocationScope;
495
+ condition: AdapterInvocationWriteCondition;
496
+ /** Compare against the current row, inside the same atomic operation. */
497
+ expectedStatuses?: readonly AdapterInvocationRecord["status"][];
498
+ mutation: {
499
+ kind: "create";
500
+ record: AdapterInvocationRecord;
501
+ } | {
502
+ kind: "update";
503
+ id: string;
504
+ patch: AdapterInvocationPatch;
505
+ };
506
+ }
507
+ export interface PlatformHostStore<TDb> {
508
+ readonly db: TDb;
509
+ /**
510
+ * Run against the store's domain handle. This base seam does not promise a
511
+ * database transaction. Use `transactionWithEvents` when domain writes,
512
+ * canonical events, and invocation state must commit atomically.
513
+ */
514
+ transaction<TResult>(run: (db: TDb) => Promise<TResult>): Promise<TResult>;
515
+ createActionInvocation(input: CreateActionInvocationInput): Promise<ActionInvocationRecord>;
516
+ getActionInvocation(id: string, tenantId: string, spaceId: string): Promise<ActionInvocationRecord | undefined>;
517
+ updateActionInvocation(id: string, tenantId: string, spaceId: string, patch: ActionInvocationPatch): Promise<void>;
518
+ appendPolicyEvaluation(record: PolicyEvaluationRecord): Promise<void>;
519
+ createAdapterInvocation(record: AdapterInvocationRecord): Promise<void>;
520
+ /**
521
+ * Optional atomic parent-authorized adapter create/update. Lease authority
522
+ * requires a running parent with the supplied owner/token; verdict authority
523
+ * requires the exact parent status/error (undefined error equals no error).
524
+ * The completion digest guards the captured completionAdapterInvocationId;
525
+ * other rows retain status/error and expectedStatuses checks. Without a captured
526
+ * row ID the digest check applies conservatively to the mutation too.
527
+ * Match tenant, space and invocation on both rows, locking the parent before
528
+ * the adapter. Return false for a predicate miss, missing parent/row, or a
529
+ * duplicate create. Updates cannot move succeeded/ambiguous to running/failed,
530
+ * even when expectedStatuses is omitted. Creation must match input.scope.
531
+ * Transaction implementations recheck predicates at commit or retain locks.
532
+ * Host uses unchecked legacy writes when this capability is absent: custom
533
+ * stores without it do not protect adapter rows against stale workers.
534
+ */
535
+ writeAdapterInvocation?(input: AdapterInvocationWriteInput): Promise<boolean>;
536
+ /**
537
+ * Atomic scoped status/error/completion compare-and-set for post-verdict enrichment.
538
+ * Expected alongside writeAdapterInvocation. When absent, Host skips only parent
539
+ * enrichment and still attempts the remaining evidence writes. Refusal is telemetry;
540
+ * thrown errors join the evidence collector.
541
+ */
542
+ updateSettledActionInvocation?(input: UpdateSettledActionInvocationInput): Promise<boolean>;
543
+ /**
544
+ * Host supplies scope from its store-loaded invocation at adapter call sites.
545
+ * When supplied, stores must match tenant, space, and action invocation:
546
+ * an out-of-scope record returns undefined. Optional for compatibility with
547
+ * existing custom stores and direct callers; tenantIsolationChecks tests
548
+ * scoped read and write conformance.
549
+ */
550
+ getAdapterInvocation(id: string, scope?: AdapterInvocationScope): Promise<AdapterInvocationRecord | undefined>;
551
+ /**
552
+ * Match all three scope fields when supplied, changing nothing outside it
553
+ * (a not-found error is permitted). Host supplies scope as described above;
554
+ * optional only for compatibility with existing stores and direct callers.
555
+ */
556
+ updateAdapterInvocation(id: string, patch: Partial<Pick<AdapterInvocationRecord, "status" | "output" | "error" | "attempt" | "updatedAt" | "reconciliation">>, scope?: AdapterInvocationScope): Promise<void>;
557
+ appendEvent(event: AssetEventEnvelope): Promise<void>;
558
+ nextEventSequence(tenantId: string, spaceId: string): Promise<number>;
559
+ /**
560
+ * Return the state and invocation writer of the same event selected by
561
+ * getEntityState, scoped to this subject and tenant/space. Return undefined
562
+ * when that event or its invocation provenance is unavailable. Transaction
563
+ * implementations include pending events visible to getEntityState.
564
+ */
565
+ getEntityStateSource?(tenantId: string, spaceId: string, entityType: string, entityId: string): Promise<{
566
+ state: string;
441
567
  actionInvocationId: string;
442
- }
443
- interface PlatformHostStore<TDb> {
444
- readonly db: TDb;
445
- /**
446
- * Run against the store's domain handle. This base seam does not promise a
447
- * database transaction. Use `transactionWithEvents` when domain writes,
448
- * canonical events, and invocation state must commit atomically.
449
- */
450
- transaction<TResult>(run: (db: TDb) => Promise<TResult>): Promise<TResult>;
451
- createActionInvocation(input: CreateActionInvocationInput): Promise<ActionInvocationRecord>;
452
- getActionInvocation(id: string, tenantId: string, spaceId: string): Promise<ActionInvocationRecord | undefined>;
453
- updateActionInvocation(id: string, tenantId: string, spaceId: string, patch: ActionInvocationPatch): Promise<void>;
454
- appendPolicyEvaluation(record: PolicyEvaluationRecord): Promise<void>;
455
- createAdapterInvocation(record: AdapterInvocationRecord): Promise<void>;
456
- /**
457
- * Host supplies scope from its store-loaded invocation at adapter call sites.
458
- * When supplied, stores must match tenant, space, and action invocation:
459
- * an out-of-scope record returns undefined. Optional for compatibility with
460
- * existing custom stores and direct callers; tenantIsolationChecks tests
461
- * scoped read and write conformance.
462
- */
463
- getAdapterInvocation(id: string, scope?: AdapterInvocationScope): Promise<AdapterInvocationRecord | undefined>;
464
- /**
465
- * Match all three scope fields when supplied, changing nothing outside it
466
- * (a not-found error is permitted). Host supplies scope as described above;
467
- * optional only for compatibility with existing stores and direct callers.
468
- */
469
- updateAdapterInvocation(id: string, patch: Partial<Pick<AdapterInvocationRecord, "status" | "output" | "error" | "attempt" | "updatedAt">>, scope?: AdapterInvocationScope): Promise<void>;
470
- appendEvent(event: AssetEventEnvelope): Promise<void>;
471
- nextEventSequence(tenantId: string, spaceId: string): Promise<number>;
472
- /**
473
- * Return the state and invocation writer of the same event selected by
474
- * getEntityState, scoped to this subject and tenant/space. Return undefined
475
- * when that event or its invocation provenance is unavailable. Transaction
476
- * implementations include pending events visible to getEntityState.
477
- */
478
- getEntityStateSource?(tenantId: string, spaceId: string, entityType: string, entityId: string): Promise<{
479
- state: string;
480
- actionInvocationId: string;
481
- } | undefined>;
482
- getEntityState(tenantId: string, spaceId: string, entityType: string, entityId: string): Promise<string | undefined>;
568
+ } | undefined>;
569
+ getEntityState(tenantId: string, spaceId: string, entityType: string, entityId: string): Promise<string | undefined>;
483
570
  }
484
571
  /**
485
572
  * Transaction-scoped Host operations used to commit domain writes and their
@@ -489,141 +576,159 @@ interface PlatformHostStore<TDb> {
489
576
  * lifecycle method on this object. Implementations must roll the whole unit
490
577
  * back when `run` throws.
491
578
  */
492
- interface PlatformHostMutationTransaction<TDb> {
493
- readonly db: TDb;
494
- /**
495
- * Read and lock an invocation until this transaction completes.
496
- * Required by serialized saga parent lifecycle transitions.
497
- */
498
- getActionInvocationForUpdate?(id: string, tenantId: string, spaceId: string): Promise<ActionInvocationRecord | undefined>;
499
- /**
500
- * Read one event by its stable identity inside the transaction.
501
- * Required by serialized saga parent lifecycle transitions.
502
- */
503
- getEvent?(id: string, tenantId: string, spaceId: string): Promise<AssetEventEnvelope | undefined>;
504
- appendEvent(event: AssetEventEnvelope): Promise<void>;
505
- appendEventWithOutbox?(event: AssetEventEnvelope, metadata: OutboxEventMetadata): Promise<void>;
506
- nextEventSequence(tenantId: string, spaceId: string): Promise<number>;
507
- listEvents(tenantId: string, spaceId: string): Promise<AssetEventEnvelope[]>;
508
- /**
509
- * Return the state and invocation writer of the same event selected by
510
- * getEntityState, scoped to this subject and tenant/space. Return undefined
511
- * when that event or its invocation provenance is unavailable. Transaction
512
- * implementations include pending events visible to getEntityState.
513
- */
514
- getEntityStateSource?(tenantId: string, spaceId: string, entityType: string, entityId: string): Promise<{
515
- state: string;
516
- actionInvocationId: string;
517
- } | undefined>;
518
- getEntityState?(tenantId: string, spaceId: string, entityType: string, entityId: string): Promise<string | undefined>;
519
- updateActionInvocation(id: string, tenantId: string, spaceId: string, patch: ActionInvocationPatch): Promise<void>;
520
- updateLeasedActionInvocation?(input: UpdateLeasedActionInvocationInput): Promise<boolean>;
521
- }
522
- type OutboxStatus = "pending" | "published" | "dead_letter";
523
- type EventPayloadClassification = "public" | "internal" | "confidential" | "restricted";
524
- interface OutboxEventMetadata {
525
- producerModuleVersion: string;
526
- payloadClassification: EventPayloadClassification;
527
- traceContext?: Record<string, string>;
528
- includeProvenance?: boolean;
529
- /**
530
- * Only `true` puts the event's `actorId` and `actorType` on the outbox envelope. Absent or any
531
- * other value leaves them off, and the outbox record says the actor was `suppressed`.
532
- */
533
- includeActor?: boolean;
579
+ export interface PlatformHostMutationTransaction<TDb> {
580
+ readonly db: TDb;
581
+ /**
582
+ * Read and lock an invocation until this transaction completes.
583
+ * Required by serialized saga parent lifecycle transitions.
584
+ */
585
+ getActionInvocationForUpdate?(id: string, tenantId: string, spaceId: string): Promise<ActionInvocationRecord | undefined>;
586
+ /**
587
+ * Read one event by its stable identity inside the transaction.
588
+ * Required by serialized saga parent lifecycle transitions.
589
+ */
590
+ getEvent?(id: string, tenantId: string, spaceId: string): Promise<AssetEventEnvelope | undefined>;
591
+ appendEvent(event: AssetEventEnvelope): Promise<void>;
592
+ appendEventWithOutbox?(event: AssetEventEnvelope, metadata: OutboxEventMetadata): Promise<void>;
593
+ nextEventSequence(tenantId: string, spaceId: string): Promise<number>;
594
+ listEvents(tenantId: string, spaceId: string): Promise<AssetEventEnvelope[]>;
595
+ /**
596
+ * Return the state and invocation writer of the same event selected by
597
+ * getEntityState, scoped to this subject and tenant/space. Return undefined
598
+ * when that event or its invocation provenance is unavailable. Transaction
599
+ * implementations include pending events visible to getEntityState.
600
+ */
601
+ getEntityStateSource?(tenantId: string, spaceId: string, entityType: string, entityId: string): Promise<{
602
+ state: string;
603
+ actionInvocationId: string;
604
+ } | undefined>;
605
+ getEntityState?(tenantId: string, spaceId: string, entityType: string, entityId: string): Promise<string | undefined>;
606
+ updateActionInvocation(id: string, tenantId: string, spaceId: string, patch: ActionInvocationPatch): Promise<void>;
607
+ updateLeasedActionInvocation?(input: UpdateLeasedActionInvocationInput): Promise<boolean>;
608
+ /**
609
+ * Update an adapter row in this transaction, with the same optional
610
+ * tenant/space/invocation scope semantics as the store method. Host uses
611
+ * this to commit degraded adapter evidence and its terminal verdict together.
612
+ * Omit this member if the adapter row cannot share this transaction.
613
+ */
614
+ updateAdapterInvocation?: PlatformHostStore<TDb>["updateAdapterInvocation"];
615
+ /** Same conditional write, sharing this transaction and its rollback. */
616
+ writeAdapterInvocation?: PlatformHostStore<TDb>["writeAdapterInvocation"];
617
+ /**
618
+ * Append governance reconciliation evidence in this transaction. Host uses
619
+ * this for overdue sweeps and degraded finalization when adapter output is
620
+ * withheld or a handoff is refused. Implement it alongside the transaction's
621
+ * invocation row lock; an outer-store append while that lock is held can
622
+ * block on a foreign key referencing the invocation. Omit this member if
623
+ * governance evidence cannot share the event/verdict transaction.
624
+ */
625
+ appendExternalReconciliation?: GovernancePlatformHostStore<TDb>["appendExternalReconciliation"];
626
+ }
627
+ export type OutboxStatus = "pending" | "published" | "dead_letter";
628
+ export type EventPayloadClassification = "public" | "internal" | "confidential" | "restricted";
629
+ export interface OutboxEventMetadata {
630
+ producerModuleVersion: string;
631
+ payloadClassification: EventPayloadClassification;
632
+ traceContext?: Record<string, string>;
633
+ includeProvenance?: boolean;
634
+ /**
635
+ * Only `true` puts the event's `actorId` and `actorType` on the outbox envelope. Absent or any
636
+ * other value leaves them off, and the outbox record says the actor was `suppressed`.
637
+ */
638
+ includeActor?: boolean;
534
639
  }
535
640
  /**
536
641
  * Whether Host put actor identity on an outbox record's envelope, decided by `includeActor` when
537
642
  * the record was written. A record has no value when it predates the decision (`legacy`).
538
643
  */
539
- type OutboxActorDisclosure = "included" | "suppressed";
644
+ export type OutboxActorDisclosure = "included" | "suppressed";
540
645
  /**
541
646
  * What the relay tells a publisher about an envelope's actor identity: the record's
542
647
  * `OutboxActorDisclosure`, or `legacy` for a record with none. The memory and PostgreSQL stores
543
648
  * hydrate actor identity only for `included` records, so their legacy and suppressed envelopes carry
544
649
  * none; a consumer that needs it reads the canonical event.
545
650
  */
546
- type EnterpriseEventActorDisclosure = OutboxActorDisclosure | "legacy";
547
- interface EnterpriseEventEnvelope {
548
- eventId: string;
549
- eventType: string;
550
- eventSchemaVersion: number;
551
- tenantId: string;
552
- spaceId: string;
553
- subjectType: string;
554
- subjectId: string;
555
- sequence: number;
556
- actionInvocationId?: string;
557
- correlationId: string;
558
- causationId?: string;
559
- /** Present only when `includeActor` opted this event in; the key is absent otherwise. */
560
- actorId?: string;
561
- /** Present only when `includeActor` opted this event in; the key is absent otherwise. */
562
- actorType?: string;
563
- occurredAt: Date;
564
- recordedAt: Date;
565
- producerModuleVersion: string;
566
- payloadClassification: EventPayloadClassification;
567
- traceContext?: Record<string, string>;
568
- provenance?: {
569
- source: InvocationSource;
570
- auditAttributes?: NamespacedAttributes;
571
- };
572
- /** Present only for events an action declaring provisional consistency emitted. */
573
- consistency?: "authoritative-now" | "provisional-until-reconciled";
574
- payload: unknown;
575
- }
576
- interface OutboxRecord {
651
+ export type EnterpriseEventActorDisclosure = OutboxActorDisclosure | "legacy";
652
+ export interface EnterpriseEventEnvelope {
653
+ eventId: string;
654
+ eventType: string;
655
+ eventSchemaVersion: number;
656
+ tenantId: string;
657
+ spaceId: string;
658
+ subjectType: string;
659
+ subjectId: string;
660
+ sequence: number;
661
+ actionInvocationId?: string;
662
+ correlationId: string;
663
+ causationId?: string;
664
+ /** Present only when `includeActor` opted this event in; the key is absent otherwise. */
665
+ actorId?: string;
666
+ /** Present only when `includeActor` opted this event in; the key is absent otherwise. */
667
+ actorType?: string;
668
+ occurredAt: Date;
669
+ recordedAt: Date;
670
+ producerModuleVersion: string;
671
+ payloadClassification: EventPayloadClassification;
672
+ traceContext?: Record<string, string>;
673
+ provenance?: {
674
+ source: InvocationSource;
675
+ auditAttributes?: NamespacedAttributes;
676
+ };
677
+ /** Present only for events an action declaring provisional consistency emitted. */
678
+ consistency?: "authoritative-now" | "provisional-until-reconciled";
679
+ payload: unknown;
680
+ }
681
+ export interface OutboxRecord {
682
+ id: string;
683
+ tenantId: string;
684
+ spaceId: string;
685
+ event: EnterpriseEventEnvelope;
686
+ /** Absent for a record written before Host recorded the `includeActor` decision. */
687
+ actorDisclosure?: OutboxActorDisclosure;
688
+ status: OutboxStatus;
689
+ attemptCount: number;
690
+ availableAt: Date;
691
+ leaseOwner?: string;
692
+ leaseExpiresAt?: Date;
693
+ leaseToken?: number;
694
+ lastError?: string;
695
+ createdAt: Date;
696
+ publishedAt?: Date;
697
+ }
698
+ export interface ClaimOutboxInput {
699
+ workerId: string;
700
+ leaseDurationMs: number;
701
+ limit?: number;
702
+ tenantId?: string;
703
+ spaceId?: string;
704
+ now?: Date;
705
+ }
706
+ export interface OutboxPlatformHostStore<TDb> extends PlatformHostStore<TDb> {
707
+ /** True only when transactionWithEvents supplies appendEventWithOutbox in the same unit of work. */
708
+ readonly transactionalOutbox?: boolean;
709
+ appendEventWithOutbox(event: AssetEventEnvelope, metadata: OutboxEventMetadata): Promise<void>;
710
+ claimOutbox(input: ClaimOutboxInput): Promise<OutboxRecord[]>;
711
+ markOutboxPublished(id: string, workerId: string, publishedAt: Date, leaseToken?: number): Promise<void>;
712
+ markOutboxFailed(input: {
577
713
  id: string;
578
- tenantId: string;
579
- spaceId: string;
580
- event: EnterpriseEventEnvelope;
581
- /** Absent for a record written before Host recorded the `includeActor` decision. */
582
- actorDisclosure?: OutboxActorDisclosure;
583
- status: OutboxStatus;
584
- attemptCount: number;
585
- availableAt: Date;
586
- leaseOwner?: string;
587
- leaseExpiresAt?: Date;
714
+ workerId: string;
588
715
  leaseToken?: number;
589
- lastError?: string;
590
- createdAt: Date;
591
- publishedAt?: Date;
592
- }
593
- interface ClaimOutboxInput {
716
+ error: string;
717
+ availableAt: Date;
718
+ deadLetter: boolean;
719
+ }): Promise<void>;
720
+ renewOutboxLease(input: {
721
+ id: string;
594
722
  workerId: string;
723
+ leaseToken: number;
595
724
  leaseDurationMs: number;
596
- limit?: number;
725
+ now?: Date;
726
+ }): Promise<boolean>;
727
+ listOutbox(input?: {
597
728
  tenantId?: string;
598
729
  spaceId?: string;
599
- now?: Date;
600
- }
601
- interface OutboxPlatformHostStore<TDb> extends PlatformHostStore<TDb> {
602
- /** True only when transactionWithEvents supplies appendEventWithOutbox in the same unit of work. */
603
- readonly transactionalOutbox?: boolean;
604
- appendEventWithOutbox(event: AssetEventEnvelope, metadata: OutboxEventMetadata): Promise<void>;
605
- claimOutbox(input: ClaimOutboxInput): Promise<OutboxRecord[]>;
606
- markOutboxPublished(id: string, workerId: string, publishedAt: Date, leaseToken?: number): Promise<void>;
607
- markOutboxFailed(input: {
608
- id: string;
609
- workerId: string;
610
- leaseToken?: number;
611
- error: string;
612
- availableAt: Date;
613
- deadLetter: boolean;
614
- }): Promise<void>;
615
- renewOutboxLease(input: {
616
- id: string;
617
- workerId: string;
618
- leaseToken: number;
619
- leaseDurationMs: number;
620
- now?: Date;
621
- }): Promise<boolean>;
622
- listOutbox(input?: {
623
- tenantId?: string;
624
- spaceId?: string;
625
- statuses?: OutboxStatus[];
626
- }): Promise<OutboxRecord[]>;
730
+ statuses?: OutboxStatus[];
731
+ }): Promise<OutboxRecord[]>;
627
732
  }
628
733
  /**
629
734
  * Append-only evidence of one operator requeue of a dead-lettered outbox
@@ -631,42 +736,42 @@ interface OutboxPlatformHostStore<TDb> extends PlatformHostStore<TDb> {
631
736
  * so the failure that exhausted the record stays readable after its attempt
632
737
  * budget is reset.
633
738
  */
634
- interface OutboxRequeueRecord {
635
- id: string;
636
- outboxId: string;
637
- tenantId: string;
638
- spaceId: string;
639
- eventId: string;
640
- actorId: string;
641
- actorType: ActorType;
642
- /** Operator-supplied justification, persisted as audit evidence. Must not carry secrets. */
643
- reason: string;
644
- requeuedAt: Date;
645
- /** When the requeued record became claimable again. */
646
- availableAt: Date;
647
- priorAttemptCount: number;
648
- priorLastError?: string;
649
- priorAvailableAt: Date;
650
- priorLeaseToken: number;
651
- }
652
- interface RequeueOutboxDeadLetterStoreInput {
653
- id: string;
654
- tenantId: string;
655
- spaceId: string;
656
- /** Identity of the evidence row written with the transition. */
657
- requeueId: string;
658
- actorId: string;
659
- actorType: ActorType;
660
- reason: string;
661
- requeuedAt: Date;
662
- availableAt: Date;
663
- /**
664
- * The lease token of the dead letter the caller read and authorized. Every
665
- * claim increments the token and a requeue never lowers it, so a record
666
- * that was requeued, claimed and dead-lettered again carries a higher token
667
- * than the one observed, and the requeue is refused as `stale`.
668
- */
669
- expectedLeaseToken: number;
739
+ export interface OutboxRequeueRecord {
740
+ id: string;
741
+ outboxId: string;
742
+ tenantId: string;
743
+ spaceId: string;
744
+ eventId: string;
745
+ actorId: string;
746
+ actorType: ActorType;
747
+ /** Operator-supplied justification, persisted as audit evidence. Must not carry secrets. */
748
+ reason: string;
749
+ requeuedAt: Date;
750
+ /** When the requeued record became claimable again. */
751
+ availableAt: Date;
752
+ priorAttemptCount: number;
753
+ priorLastError?: string;
754
+ priorAvailableAt: Date;
755
+ priorLeaseToken: number;
756
+ }
757
+ export interface RequeueOutboxDeadLetterStoreInput {
758
+ id: string;
759
+ tenantId: string;
760
+ spaceId: string;
761
+ /** Identity of the evidence row written with the transition. */
762
+ requeueId: string;
763
+ actorId: string;
764
+ actorType: ActorType;
765
+ reason: string;
766
+ requeuedAt: Date;
767
+ availableAt: Date;
768
+ /**
769
+ * The lease token of the dead letter the caller read and authorized. Every
770
+ * claim increments the token and a requeue never lowers it, so a record
771
+ * that was requeued, claimed and dead-lettered again carries a higher token
772
+ * than the one observed, and the requeue is refused as `stale`.
773
+ */
774
+ expectedLeaseToken: number;
670
775
  }
671
776
  /**
672
777
  * `not_found`: no record with this id in the tenant and space, including a
@@ -675,74 +780,74 @@ interface RequeueOutboxDeadLetterStoreInput {
675
780
  * requeue won the compare-and-set. `stale`: the record is a dead letter
676
781
  * again, but not the one the caller observed; read and authorize it afresh.
677
782
  */
678
- type OutboxRequeueRefusal = "not_found" | "not_dead_letter" | "stale";
679
- type RequeueOutboxDeadLetterStoreResult = {
680
- applied: true;
681
- record: OutboxRecord;
682
- requeue: OutboxRequeueRecord;
783
+ export type OutboxRequeueRefusal = "not_found" | "not_dead_letter" | "stale";
784
+ export type RequeueOutboxDeadLetterStoreResult = {
785
+ applied: true;
786
+ record: OutboxRecord;
787
+ requeue: OutboxRequeueRecord;
683
788
  } | {
684
- applied: false;
685
- refusal: OutboxRequeueRefusal;
686
- currentStatus?: OutboxStatus;
789
+ applied: false;
790
+ refusal: OutboxRequeueRefusal;
791
+ currentStatus?: OutboxStatus;
687
792
  };
688
793
  /**
689
794
  * Optional outbox capability that moves a dead-lettered record back to
690
795
  * pending. Kept apart from `OutboxPlatformHostStore` so a custom outbox store
691
796
  * that predates it still satisfies that interface.
692
797
  */
693
- interface OutboxRequeuePlatformHostStore<TDb> extends OutboxPlatformHostStore<TDb> {
694
- getOutboxRecord(id: string, tenantId: string, spaceId: string): Promise<OutboxRecord | undefined>;
695
- /**
696
- * Compare-and-set from `dead_letter` at `expectedLeaseToken` to `pending`
697
- * within the tenant and space: resets `attemptCount` to 0, sets
698
- * `availableAt`, clears any lease owner while keeping the lease token,
699
- * keeps `lastError`, and appends one `OutboxRequeueRecord` in the same
700
- * atomic step. A record in any other state, at another lease token, or in
701
- * another scope is refused and nothing is written. The returned requeue
702
- * evidence shares nothing with stored history. The returned outbox record
703
- * has its own Date fields; its event payload and provenance are shallow.
704
- */
705
- requeueOutboxDeadLetter(input: RequeueOutboxDeadLetterStoreInput): Promise<RequeueOutboxDeadLetterStoreResult>;
706
- /** Requeue evidence for a scope, oldest first; `outboxId` narrows it to one record. */
707
- listOutboxRequeues(input: {
708
- tenantId: string;
709
- spaceId: string;
710
- outboxId?: string;
711
- }): Promise<OutboxRequeueRecord[]>;
712
- }
713
- interface RequeueOutboxDeadLetterInput {
714
- outboxId: string;
798
+ export interface OutboxRequeuePlatformHostStore<TDb> extends OutboxPlatformHostStore<TDb> {
799
+ getOutboxRecord(id: string, tenantId: string, spaceId: string): Promise<OutboxRecord | undefined>;
800
+ /**
801
+ * Compare-and-set from `dead_letter` at `expectedLeaseToken` to `pending`
802
+ * within the tenant and space: resets `attemptCount` to 0, sets
803
+ * `availableAt`, clears any lease owner while keeping the lease token,
804
+ * keeps `lastError`, and appends one `OutboxRequeueRecord` in the same
805
+ * atomic step. A record in any other state, at another lease token, or in
806
+ * another scope is refused and nothing is written. The returned requeue
807
+ * evidence shares nothing with stored history. The returned outbox record
808
+ * has its own Date fields; its event payload and provenance are shallow.
809
+ */
810
+ requeueOutboxDeadLetter(input: RequeueOutboxDeadLetterStoreInput): Promise<RequeueOutboxDeadLetterStoreResult>;
811
+ /** Requeue evidence for a scope, oldest first; `outboxId` narrows it to one record. */
812
+ listOutboxRequeues(input: {
715
813
  tenantId: string;
716
814
  spaceId: string;
717
- /** Trusted operator identity from the caller's authenticated session, never from request input. */
718
- actorId: string;
719
- actorType: ActorType;
720
- /** Required justification, at most 1,000 characters, persisted as audit evidence. */
721
- reason: string;
722
- /** When the record becomes claimable again; defaults to the host clock. */
723
- availableAt?: Date;
724
- }
725
- type RequeueOutboxDeadLetterRefusal = OutboxRequeueRefusal | "not_authorized";
726
- type RequeueOutboxDeadLetterResult = {
727
- status: "requeued";
728
- record: OutboxRecord;
729
- requeue: OutboxRequeueRecord;
815
+ outboxId?: string;
816
+ }): Promise<OutboxRequeueRecord[]>;
817
+ }
818
+ export interface RequeueOutboxDeadLetterInput {
819
+ outboxId: string;
820
+ tenantId: string;
821
+ spaceId: string;
822
+ /** Trusted operator identity from the caller's authenticated session, never from request input. */
823
+ actorId: string;
824
+ actorType: ActorType;
825
+ /** Required justification, at most 1,000 characters, persisted as audit evidence. */
826
+ reason: string;
827
+ /** When the record becomes claimable again; defaults to the host clock. */
828
+ availableAt?: Date;
829
+ }
830
+ export type RequeueOutboxDeadLetterRefusal = OutboxRequeueRefusal | "not_authorized";
831
+ export type RequeueOutboxDeadLetterResult = {
832
+ status: "requeued";
833
+ record: OutboxRecord;
834
+ requeue: OutboxRequeueRecord;
730
835
  } | {
731
- status: "refused";
732
- refusal: RequeueOutboxDeadLetterRefusal;
733
- /** Present for `not_dead_letter` and `stale`: the state the record was found in. */
734
- currentStatus?: OutboxStatus;
735
- message: string;
836
+ status: "refused";
837
+ refusal: RequeueOutboxDeadLetterRefusal;
838
+ /** Present for `not_dead_letter` and `stale`: the state the record was found in. */
839
+ currentStatus?: OutboxStatus;
840
+ message: string;
736
841
  };
737
842
  /** Facts given to `authorizeOutboxRequeue`. `record` is absent when no record with this id exists in the scope. */
738
- interface OutboxRequeueAuthorizationInput {
739
- tenantId: string;
740
- spaceId: string;
741
- actorId: string;
742
- actorType: ActorType;
743
- outboxId: string;
744
- reason: string;
745
- record?: Pick<OutboxRecord["event"], "eventId" | "eventType" | "payloadClassification"> & Pick<OutboxRecord, "status" | "attemptCount">;
843
+ export interface OutboxRequeueAuthorizationInput {
844
+ tenantId: string;
845
+ spaceId: string;
846
+ actorId: string;
847
+ actorType: ActorType;
848
+ outboxId: string;
849
+ reason: string;
850
+ record?: Pick<OutboxRecord["event"], "eventId" | "eventType" | "payloadClassification"> & Pick<OutboxRecord, "status" | "attemptCount">;
746
851
  }
747
852
  /**
748
853
  * Optional production capability for atomic domain/event persistence.
@@ -751,60 +856,60 @@ interface OutboxRequeueAuthorizationInput {
751
856
  * not implement it retain the legacy transaction boundary for compatibility,
752
857
  * but cannot claim atomic domain-write/event persistence.
753
858
  */
754
- interface AtomicMutationPlatformHostStore<TDb> extends PlatformHostStore<TDb> {
755
- transactionWithEvents<TResult>(run: (transaction: PlatformHostMutationTransaction<TDb>) => Promise<TResult>): Promise<TResult>;
756
- }
757
- interface BeginApprovalDecisionInput {
758
- actionInvocationId: string;
759
- tenantId: string;
760
- spaceId: string;
761
- decision: PersistedActionApprovalDecision;
762
- leaseOwner: string;
763
- leaseDurationMs: number;
764
- now: Date;
765
- }
766
- interface ApprovalDecisionTransitionResult {
767
- applied: boolean;
768
- invocation?: ActionInvocationRecord;
859
+ export interface AtomicMutationPlatformHostStore<TDb> extends PlatformHostStore<TDb> {
860
+ transactionWithEvents<TResult>(run: (transaction: PlatformHostMutationTransaction<TDb>) => Promise<TResult>): Promise<TResult>;
861
+ }
862
+ export interface BeginApprovalDecisionInput {
863
+ actionInvocationId: string;
864
+ tenantId: string;
865
+ spaceId: string;
866
+ decision: PersistedActionApprovalDecision;
867
+ leaseOwner: string;
868
+ leaseDurationMs: number;
869
+ now: Date;
870
+ }
871
+ export interface ApprovalDecisionTransitionResult {
872
+ applied: boolean;
873
+ invocation?: ActionInvocationRecord;
769
874
  }
770
875
  /** Optional store capability required only when agent HITL or approval resume is used. */
771
- interface ApprovalPlatformHostStore<TDb> extends PlatformHostStore<TDb> {
772
- recordHitlDecision(actionInvocationId: string, tenantId: string, spaceId: string, decision: HitlDecisionEvidence): Promise<ActionInvocationRecord>;
773
- beginApprovalDecision(input: BeginApprovalDecisionInput): Promise<ApprovalDecisionTransitionResult>;
876
+ export interface ApprovalPlatformHostStore<TDb> extends PlatformHostStore<TDb> {
877
+ recordHitlDecision(actionInvocationId: string, tenantId: string, spaceId: string, decision: HitlDecisionEvidence): Promise<ActionInvocationRecord>;
878
+ beginApprovalDecision(input: BeginApprovalDecisionInput): Promise<ApprovalDecisionTransitionResult>;
774
879
  }
775
880
  /** Optional durable capabilities used when external-governance enrichment is configured. */
776
- interface GovernancePlatformHostStore<TDb> extends PlatformHostStore<TDb> {
777
- recordMutationGovernance(actionInvocationId: string, tenantId: string, spaceId: string, context: {
778
- footprint: MutationFootprint;
779
- executionPrincipal: ExecutionPrincipal;
780
- }): Promise<ActionInvocationRecord>;
781
- appendPolicyObligations(records: PolicyObligationRecord[]): Promise<void>;
782
- listPolicyObligations(actionInvocationId: string, tenantId: string, spaceId: string): Promise<PolicyObligationRecord[]>;
783
- updatePolicyObligation(actionInvocationId: string, obligationId: string, status: PolicyObligationStatus, evidenceReferences?: PolicyObligation["evidenceReferences"]): Promise<void>;
784
- appendExecutionAttestation(record: ExecutionAttestationRecord): Promise<void>;
785
- listExecutionAttestations(actionInvocationId: string, tenantId: string, spaceId: string): Promise<ExecutionAttestationRecord[]>;
786
- appendExternalReconciliation(record: ExternalReconciliationRecord): Promise<void>;
787
- }
788
- interface ListActionInvocationsInput {
789
- tenantId?: string;
790
- spaceId?: string;
791
- statuses?: readonly ActionStatus[];
792
- updatedBefore?: Date;
793
- /** Only invocations holding a pending external completion. */
794
- awaitingCompletion?: boolean;
795
- /** Only pending completions due at or before this instant. Implies `awaitingCompletion`. */
796
- completionDueBefore?: Date;
797
- /** Only invocations no worker holds a lease on. */
798
- unleased?: boolean;
799
- limit?: number;
800
- }
801
- interface ClaimActionInvocationsInput {
802
- workerId: string;
803
- leaseDurationMs: number;
804
- limit?: number;
805
- tenantId?: string;
806
- spaceId?: string;
807
- now?: Date;
881
+ export interface GovernancePlatformHostStore<TDb> extends PlatformHostStore<TDb> {
882
+ recordMutationGovernance(actionInvocationId: string, tenantId: string, spaceId: string, context: {
883
+ footprint: MutationFootprint;
884
+ executionPrincipal: ExecutionPrincipal;
885
+ }): Promise<ActionInvocationRecord>;
886
+ appendPolicyObligations(records: PolicyObligationRecord[]): Promise<void>;
887
+ listPolicyObligations(actionInvocationId: string, tenantId: string, spaceId: string): Promise<PolicyObligationRecord[]>;
888
+ updatePolicyObligation(actionInvocationId: string, obligationId: string, status: PolicyObligationStatus, evidenceReferences?: PolicyObligation["evidenceReferences"]): Promise<void>;
889
+ appendExecutionAttestation(record: ExecutionAttestationRecord): Promise<void>;
890
+ listExecutionAttestations(actionInvocationId: string, tenantId: string, spaceId: string): Promise<ExecutionAttestationRecord[]>;
891
+ appendExternalReconciliation(record: ExternalReconciliationRecord): Promise<void>;
892
+ }
893
+ export interface ListActionInvocationsInput {
894
+ tenantId?: string;
895
+ spaceId?: string;
896
+ statuses?: readonly ActionStatus[];
897
+ updatedBefore?: Date;
898
+ /** Only invocations holding a pending external completion. */
899
+ awaitingCompletion?: boolean;
900
+ /** Only pending completions due at or before this instant. Implies `awaitingCompletion`. */
901
+ completionDueBefore?: Date;
902
+ /** Only invocations no worker holds a lease on. */
903
+ unleased?: boolean;
904
+ limit?: number;
905
+ }
906
+ export interface ClaimActionInvocationsInput {
907
+ workerId: string;
908
+ leaseDurationMs: number;
909
+ limit?: number;
910
+ tenantId?: string;
911
+ spaceId?: string;
912
+ now?: Date;
808
913
  }
809
914
  /**
810
915
  * What the host writes back to an invocation.
@@ -819,55 +924,55 @@ interface ClaimActionInvocationsInput {
819
924
  * - `claimActionInvocations` must never claim a running invocation without a
820
925
  * lease, which is what a parked invocation is.
821
926
  */
822
- type ActionInvocationPatch = Partial<Pick<ActionInvocationRecord, "status" | "result" | "error" | "authorizationReconciliation" | "adapterReconciliation" | "pendingCompletion" | "externalCompletion">>;
823
- interface UpdateLeasedActionInvocationInput {
824
- id: string;
825
- tenantId: string;
826
- spaceId: string;
827
- workerId: string;
828
- leaseToken: number;
829
- patch: ActionInvocationPatch;
830
- }
831
- interface RenewActionInvocationLeaseInput {
832
- id: string;
833
- tenantId: string;
834
- spaceId: string;
835
- workerId: string;
836
- leaseToken: number;
837
- leaseDurationMs: number;
838
- now?: Date;
927
+ export type ActionInvocationPatch = Partial<Pick<ActionInvocationRecord, "status" | "result" | "error" | "authorizationReconciliation" | "adapterReconciliation" | "pendingStateTransition" | "pendingCompletion" | "externalCompletion">>;
928
+ export interface UpdateLeasedActionInvocationInput {
929
+ id: string;
930
+ tenantId: string;
931
+ spaceId: string;
932
+ workerId: string;
933
+ leaseToken: number;
934
+ patch: ActionInvocationPatch;
935
+ }
936
+ export interface RenewActionInvocationLeaseInput {
937
+ id: string;
938
+ tenantId: string;
939
+ spaceId: string;
940
+ workerId: string;
941
+ leaseToken: number;
942
+ leaseDurationMs: number;
943
+ now?: Date;
839
944
  }
840
945
  /** Store capabilities required by the durable polling worker and operator tooling. */
841
- interface RecoverablePlatformHostStore<TDb> extends PlatformHostStore<TDb> {
842
- listActionInvocations(input?: ListActionInvocationsInput): Promise<ActionInvocationRecord[]>;
843
- claimActionInvocations(input: ClaimActionInvocationsInput): Promise<ActionInvocationRecord[]>;
844
- updateLeasedActionInvocation(input: UpdateLeasedActionInvocationInput): Promise<boolean>;
845
- renewActionInvocationLease(input: RenewActionInvocationLeaseInput): Promise<boolean>;
846
- listEvents(tenantId: string, spaceId: string): Promise<AssetEventEnvelope[]>;
847
- }
848
- interface ActionAuthorizationInput {
849
- actionId: ActionId;
850
- namespace: string;
851
- requiredPermissions: readonly string[];
852
- requiredRoles: readonly string[];
853
- tenantId: string;
854
- spaceId: string;
855
- actorId: string;
856
- actorType: ActorType;
857
- }
858
- type KnownActionExecutionReason = "initial" | "approval_resume" | "recovery" | "offline_replay";
859
- type ActionExecutionReason = KnownActionExecutionReason | (string & {});
946
+ export interface RecoverablePlatformHostStore<TDb> extends PlatformHostStore<TDb> {
947
+ listActionInvocations(input?: ListActionInvocationsInput): Promise<ActionInvocationRecord[]>;
948
+ claimActionInvocations(input: ClaimActionInvocationsInput): Promise<ActionInvocationRecord[]>;
949
+ updateLeasedActionInvocation(input: UpdateLeasedActionInvocationInput): Promise<boolean>;
950
+ renewActionInvocationLease(input: RenewActionInvocationLeaseInput): Promise<boolean>;
951
+ listEvents(tenantId: string, spaceId: string): Promise<AssetEventEnvelope[]>;
952
+ }
953
+ export interface ActionAuthorizationInput {
954
+ actionId: ActionId;
955
+ namespace: string;
956
+ requiredPermissions: readonly string[];
957
+ requiredRoles: readonly string[];
958
+ tenantId: string;
959
+ spaceId: string;
960
+ actorId: string;
961
+ actorType: ActorType;
962
+ }
963
+ export type KnownActionExecutionReason = "initial" | "approval_resume" | "recovery" | "offline_replay";
964
+ export type ActionExecutionReason = KnownActionExecutionReason | (string & {});
860
965
  /**
861
966
  * Trusted execution-boundary authorization input.
862
967
  *
863
968
  * Parameters are the schema-parsed durable parameters, never caller-supplied
864
969
  * transient values. `invocation` is the canonical record that will execute.
865
970
  */
866
- interface ActionExecutionAuthorizationInput extends ActionAuthorizationInput {
867
- actionInvocationId: string;
868
- parameters: unknown;
869
- invocation: Readonly<ActionInvocationRecord>;
870
- executionReason: ActionExecutionReason;
971
+ export interface ActionExecutionAuthorizationInput extends ActionAuthorizationInput {
972
+ actionInvocationId: string;
973
+ parameters: unknown;
974
+ invocation: Readonly<ActionInvocationRecord>;
975
+ executionReason: ActionExecutionReason;
871
976
  }
872
977
  /**
873
978
  * Input to `resolvePolicies`. Carries the invocation identity and the
@@ -876,41 +981,41 @@ interface ActionExecutionAuthorizationInput extends ActionAuthorizationInput {
876
981
  * persisted evaluation per invocation and policy, so return the same snapshot
877
982
  * for an `actionInvocationId` on every attempt.
878
983
  */
879
- interface ResolvePoliciesInput extends ActionExecutionAuthorizationInput {
880
- declaredPolicyIds: readonly string[];
881
- }
882
- interface PlatformHostAuthorization {
883
- checkEntitlement(input: ActionAuthorizationInput): Promise<boolean>;
884
- authorize(input: ActionAuthorizationInput): Promise<boolean>;
885
- /**
886
- * Optional final authorization immediately before policies and mutation
887
- * execution. When absent, the Host reuses `authorize` at this boundary.
888
- */
889
- authorizeExecution?(input: ActionExecutionAuthorizationInput): Promise<boolean>;
890
- /** Optional distinct authorization boundary for human/system approval decisions. */
891
- authorizeApproval?(input: ActionAuthorizationInput & {
892
- decision: ActionApprovalDecision;
893
- }): Promise<boolean>;
894
- /**
895
- * Authorization for `requeueOutboxDeadLetter`. There is no action to fall
896
- * back to, so when this is absent every requeue is refused as
897
- * `not_authorized`. A throw propagates and nothing is requeued.
898
- */
899
- authorizeOutboxRequeue?(input: OutboxRequeueAuthorizationInput): Promise<boolean>;
900
- }
901
- interface DispatchActionInput {
902
- actionInvocationId: string;
903
- actionId: ActionId;
904
- tenantId: string;
905
- spaceId: string;
906
- workflowId: string;
907
- }
908
- interface DispatchActionResult {
909
- workflowId: string;
910
- runId?: string;
911
- }
912
- interface PlatformActionDispatcher {
913
- dispatch(input: DispatchActionInput): Promise<DispatchActionResult>;
984
+ export interface ResolvePoliciesInput extends ActionExecutionAuthorizationInput {
985
+ declaredPolicyIds: readonly string[];
986
+ }
987
+ export interface PlatformHostAuthorization {
988
+ checkEntitlement(input: ActionAuthorizationInput): Promise<boolean>;
989
+ authorize(input: ActionAuthorizationInput): Promise<boolean>;
990
+ /**
991
+ * Optional final authorization immediately before policies and mutation
992
+ * execution. When absent, the Host reuses `authorize` at this boundary.
993
+ */
994
+ authorizeExecution?(input: ActionExecutionAuthorizationInput): Promise<boolean>;
995
+ /** Optional distinct authorization boundary for human/system approval decisions. */
996
+ authorizeApproval?(input: ActionAuthorizationInput & {
997
+ decision: ActionApprovalDecision;
998
+ }): Promise<boolean>;
999
+ /**
1000
+ * Authorization for `requeueOutboxDeadLetter`. There is no action to fall
1001
+ * back to, so when this is absent every requeue is refused as
1002
+ * `not_authorized`. A throw propagates and nothing is requeued.
1003
+ */
1004
+ authorizeOutboxRequeue?(input: OutboxRequeueAuthorizationInput): Promise<boolean>;
1005
+ }
1006
+ export interface DispatchActionInput {
1007
+ actionInvocationId: string;
1008
+ actionId: ActionId;
1009
+ tenantId: string;
1010
+ spaceId: string;
1011
+ workflowId: string;
1012
+ }
1013
+ export interface DispatchActionResult {
1014
+ workflowId: string;
1015
+ runId?: string;
1016
+ }
1017
+ export interface PlatformActionDispatcher {
1018
+ dispatch(input: DispatchActionInput): Promise<DispatchActionResult>;
914
1019
  }
915
1020
  /**
916
1021
  * One submission. `submitAction` reads the scalar fields (`actionId`, scope,
@@ -924,452 +1029,474 @@ interface PlatformActionDispatcher {
924
1029
  * as the caller's objects, read where and as often as before (README,
925
1030
  * "Submission snapshot").
926
1031
  */
927
- interface SubmitActionInput {
928
- actionId: ActionId;
929
- parameters: Record<string, unknown>;
930
- tenantId: string;
931
- spaceId: string;
932
- actorId: string;
933
- actorType: ActorType;
934
- correlationId?: string;
935
- causationId?: string;
936
- provenance?: InvocationProvenance;
937
- executionReason?: Extract<KnownActionExecutionReason, "initial" | "offline_replay">;
938
- /** Stable logical command key. Reusing it returns the original invocation; a pending failed dispatch may retry its stable workflow ID. */
939
- idempotencyKey?: string;
940
- /** Opaque, non-secret authorization/admission reference persisted with the invocation. */
941
- authorizationBindingId?: string;
942
- authorizationBinding?: AuthorizationBinding;
943
- }
944
- interface SubmitActionResult {
945
- actionInvocationId: string;
946
- status: ActionStatus;
947
- workflowId: string;
948
- runId?: string;
949
- result?: Record<string, unknown>;
950
- error?: string;
951
- reconciliation?: AuthorizationReconciliationOutcome;
952
- adapterReconciliation?: AdapterReconciliationOutcome;
953
- /** Present while the invocation waits for an external system to complete it. */
954
- pendingCompletion?: PendingExternalCompletion;
955
- /** Mirrors the action's declared consistency so a caller knows whether the result is settled. */
956
- consistency?: "authoritative-now" | "provisional-until-reconciled";
957
- hitlRoute?: AgentActionRoute;
958
- hitlRiskTier?: AgentActionRiskTier;
959
- }
960
- interface ExecuteActionResult {
961
- actionInvocationId: string;
962
- status: ActionStatus;
963
- result?: Record<string, unknown>;
964
- error?: string;
965
- reconciliation?: AuthorizationReconciliationOutcome;
966
- adapterReconciliation?: AdapterReconciliationOutcome;
967
- /** Present while the invocation waits for an external system to complete it. */
968
- pendingCompletion?: PendingExternalCompletion;
969
- /** Mirrors the action's declared consistency so a caller knows whether the result is settled. */
970
- consistency?: "authoritative-now" | "provisional-until-reconciled";
971
- hitlRoute?: AgentActionRoute;
972
- hitlRiskTier?: AgentActionRiskTier;
973
- }
974
- interface ExecuteInvocationOptions {
975
- /** Required when executing a row already protected by a worker or approval-resume lease. */
976
- leaseOwner?: string;
977
- /** Claim generation paired with leaseOwner; stale generations are rejected. */
978
- leaseToken?: number;
979
- }
980
- interface PlatformActionWorkerOptions<TDb> {
981
- host: GovernedActionHost;
982
- store: RecoverablePlatformHostStore<TDb>;
983
- workerId: string;
984
- batchSize?: number;
985
- leaseDurationMs?: number;
986
- leaseRenewalIntervalMs?: number;
987
- pollIntervalMs?: number;
988
- tenantId?: string;
989
- spaceId?: string;
990
- signal?: AbortSignal;
991
- onError?: (error: unknown, invocation?: ActionInvocationRecord) => void;
992
- telemetry?: PlatformHostTelemetry;
993
- /**
994
- * Sweep overdue external handoffs each cycle. Defaults to on. Turn it off
995
- * for a store without the governance seam, where the sweep would refuse
996
- * on every cycle, and run the sweep elsewhere.
997
- */
998
- sweepOverdueCompletions?: boolean;
999
- }
1000
- interface PlatformActionWorkerCycleResult {
1001
- claimed: number;
1002
- completed: number;
1003
- failed: number;
1004
- /** Present when claimed agent work was durably parked instead of failing. */
1005
- waitingForApproval?: number;
1006
- /**
1007
- * Present only when > 0: claimed invocations whose execution threw a
1008
- * RetryableExecutionError (counted by error type, not by where it was thrown).
1009
- * The row stays leased and a later claim retries it; excluded from failed.
1010
- */
1011
- deferred?: number;
1032
+ export interface SubmitActionInput {
1033
+ actionId: ActionId;
1034
+ parameters: Record<string, unknown>;
1035
+ tenantId: string;
1036
+ spaceId: string;
1037
+ actorId: string;
1038
+ actorType: ActorType;
1039
+ correlationId?: string;
1040
+ causationId?: string;
1041
+ provenance?: InvocationProvenance;
1042
+ executionReason?: Extract<KnownActionExecutionReason, "initial" | "offline_replay">;
1043
+ /** Stable logical command key. Reusing it returns the original invocation; a pending failed dispatch may retry its stable workflow ID. */
1044
+ idempotencyKey?: string;
1045
+ /** Opaque, non-secret authorization/admission reference persisted with the invocation. */
1046
+ authorizationBindingId?: string;
1047
+ authorizationBinding?: AuthorizationBinding;
1048
+ }
1049
+ export interface SubmitActionResult {
1050
+ actionInvocationId: string;
1051
+ status: ActionStatus;
1052
+ workflowId: string;
1053
+ runId?: string;
1054
+ result?: Record<string, unknown>;
1055
+ error?: string;
1056
+ reconciliation?: AuthorizationReconciliationOutcome;
1057
+ adapterReconciliation?: AdapterReconciliationOutcome;
1058
+ /** Present while the invocation waits for an external system to complete it. */
1059
+ pendingCompletion?: PendingExternalCompletion;
1060
+ /** Mirrors the action's declared consistency so a caller knows whether the result is settled. */
1061
+ consistency?: "authoritative-now" | "provisional-until-reconciled";
1062
+ hitlRoute?: AgentActionRoute;
1063
+ hitlRiskTier?: AgentActionRiskTier;
1064
+ }
1065
+ export interface ExecuteActionResult {
1066
+ actionInvocationId: string;
1067
+ status: ActionStatus;
1068
+ result?: Record<string, unknown>;
1069
+ error?: string;
1070
+ reconciliation?: AuthorizationReconciliationOutcome;
1071
+ adapterReconciliation?: AdapterReconciliationOutcome;
1072
+ /** Present while the invocation waits for an external system to complete it. */
1073
+ pendingCompletion?: PendingExternalCompletion;
1074
+ /** Mirrors the action's declared consistency so a caller knows whether the result is settled. */
1075
+ consistency?: "authoritative-now" | "provisional-until-reconciled";
1076
+ hitlRoute?: AgentActionRoute;
1077
+ hitlRiskTier?: AgentActionRiskTier;
1078
+ }
1079
+ export interface ExecuteInvocationOptions {
1080
+ /** Required when executing a row already protected by a worker or approval-resume lease. */
1081
+ leaseOwner?: string;
1082
+ /** Claim generation paired with leaseOwner; stale generations are rejected. */
1083
+ leaseToken?: number;
1084
+ }
1085
+ export interface PlatformActionWorkerOptions<TDb> {
1086
+ host: GovernedActionHost;
1087
+ store: RecoverablePlatformHostStore<TDb>;
1088
+ workerId: string;
1089
+ batchSize?: number;
1090
+ leaseDurationMs?: number;
1091
+ leaseRenewalIntervalMs?: number;
1092
+ pollIntervalMs?: number;
1093
+ tenantId?: string;
1094
+ spaceId?: string;
1095
+ signal?: AbortSignal;
1096
+ onError?: (error: unknown, invocation?: ActionInvocationRecord) => void;
1097
+ telemetry?: PlatformHostTelemetry;
1098
+ /**
1099
+ * Sweep overdue external handoffs each cycle. Defaults to on. Turn it off
1100
+ * for a store without the governance seam, where the sweep would refuse
1101
+ * on every cycle, and run the sweep elsewhere.
1102
+ */
1103
+ sweepOverdueCompletions?: boolean;
1104
+ }
1105
+ export interface PlatformActionWorkerCycleResult {
1106
+ claimed: number;
1107
+ completed: number;
1108
+ failed: number;
1109
+ /** Present when claimed agent work was durably parked instead of failing. */
1110
+ waitingForApproval?: number;
1111
+ /**
1112
+ * Present only when > 0: claimed invocations whose execution threw a
1113
+ * RetryableExecutionError (counted by error type, not by where it was thrown).
1114
+ * The row stays leased and a later claim retries it; excluded from failed.
1115
+ */
1116
+ deferred?: number;
1012
1117
  }
1013
1118
  /** Origin of error text redacted before Host records or returns it. */
1014
- interface ErrorTextRedactionContext {
1015
- actionId: ActionId;
1016
- source: "handler" | "adapter" | "external_completion" | "execution";
1017
- adapterType?: string;
1018
- operation?: string;
1019
- /** Adapter vendor or external completion provider. */
1020
- provider?: string;
1021
- }
1022
- interface PlatformHostOptions<TDb> {
1023
- store: PlatformHostStore<TDb>;
1024
- authorization: PlatformHostAuthorization;
1025
- /** Preferred explicit catalog assembled from this runtime's Fabric modules. */
1026
- registry?: Pick<ModuleRegistry<TDb>, "resolveAction" | "resolvePolicy" | "resolveStateMachine"> & Partial<Pick<ModuleRegistry<TDb>, "orderedModules">>;
1027
- /** Resolve vertical- or runtime-local actions without mutating the process-wide registry. */
1028
- resolveAction?: (actionId: ActionId) => ActionDefinition<TDb> | undefined;
1029
- adapters?: readonly AdapterImplementation[];
1030
- /**
1031
- * Supplies the circuit breaker for each adapter call. Defaults to a new
1032
- * `AdapterCircuitBreakerRegistry` per Host instance, which creates one
1033
- * in-process breaker per `adapterType:operation` from that adapter's own
1034
- * `circuitBreaker` config, on first use, and none for adapters without one.
1035
- * Pass a shared registry or a custom provider to share breakers between
1036
- * Host instances, receive breaker telemetry, or set manual overrides.
1037
- * The default key shares failures across tenants and vendors in a registry.
1038
- * Use `new AdapterCircuitBreakerRegistry({ key: scopedAdapterCircuitBreakerKey })`
1039
- * for tenant/space/vendor isolation. Host passes trusted tenant/space scope
1040
- * to the provider. The registry keeps the first config seen for a key;
1041
- * later conflicting configs reuse that breaker without throwing. Breakers
1042
- * are never evicted, so scoped keys keep one breaker per scope seen.
1043
- */
1044
- adapterCircuitBreakers?: AdapterCircuitBreakerProvider;
1045
- /**
1046
- * Positive integer attempt cap for RetryableExecutionError during governance,
1047
- * before policy-evaluation persistence (default 5). A leased, idempotent action
1048
- * below the cap is left running for worker reclaim after lease expiry.
1049
- * Inline execution, approval resume, exhausted attempts, and non-idempotent
1050
- * actions fail. Policy persistence, obligation listing/resolution/persistence, state-machine checks,
1051
- * the handler transaction, handlers, adapters, and finalization are excluded;
1052
- * their existing failure/reconciliation/recovery semantics apply.
1053
- */
1054
- retryableExecutionMaxAttempts?: number;
1055
- dispatcher?: PlatformActionDispatcher;
1056
- services?: FabricRuntimeServices;
1057
- idempotency?: {
1058
- conflictMode?: "audit-only" | "enforce";
1059
- onConflict?(conflict: IdempotencyConflict): void;
1060
- onLegacyRecord?(invocation: ActionInvocationRecord): void;
1061
- };
1062
- provenance?: {
1063
- auditAttributeAllowlist?: readonly string[];
1064
- maxAttributes?: number;
1065
- maxValueLength?: number;
1066
- redactAuditAttributes?(attributes: NamespacedAttributes): NamespacedAttributes;
1067
- onTrace?(provenance: InvocationProvenance): void;
1068
- };
1069
- /** Requires an outbox-capable store; every canonical event is then appended with delivery state. */
1070
- outbox?: {
1071
- producerModuleVersion(actionId: ActionId, actionVersion: number): string;
1072
- classifyPayload(event: AssetEventEnvelope): EventPayloadClassification;
1073
- includeProvenance?(event: AssetEventEnvelope, classification: EventPayloadClassification): boolean;
1074
- /**
1075
- * Opt an event's `actorId` and `actorType` into its outbox envelope. Absent, the actor is
1076
- * excluded for every classification. Only `true` includes it. An included actor reaches every
1077
- * sink of every relay reading this outbox.
1078
- */
1079
- includeActor?(event: AssetEventEnvelope, classification: EventPayloadClassification): boolean;
1080
- traceContext?(event: AssetEventEnvelope): Record<string, string> | undefined;
1081
- /** Host lifecycle events are excluded by default; opt in only after making their payload audit-safe. */
1082
- shouldPublish?(event: AssetEventEnvelope): boolean;
1083
- };
1084
- /** Optional vertical-owned evaluator. When absent, agent behavior is unchanged. */
1085
- hitlEvaluator?: AgentActionPolicyEvaluator;
1086
- /** Durable evaluator/ruleset version recorded with every HITL decision. */
1087
- hitlPolicyVersion?: string;
1088
- /** Optional portable resolver; provider-specific implementations belong in integration packages. */
1089
- resolveMutationGovernance?: MutationGovernanceResolver;
1090
- /** Translate policy outcomes into durable, enforceable obligations. */
1091
- resolvePolicyObligations?: (outcomes: readonly PolicyOutcome[]) => Promise<PolicyObligation[]> | PolicyObligation[];
1092
- /** Translate a successful adapter result into audit-safe external execution evidence. */
1093
- extractExecutionAttestation?: (input: {
1094
- actionInvocationId: string;
1095
- adapterInvocationId: string;
1096
- adapterType: string;
1097
- operation: string;
1098
- vendor: string;
1099
- /** Audit-safe adapter input after redactAdapterInput has been applied. */
1100
- input: Record<string, unknown>;
1101
- startedAt: Date;
1102
- completedAt: Date;
1103
- /** Adapter output after redactAdapterOutput, when configured. */
1104
- output: Record<string, unknown>;
1105
- }) => Promise<ExecutionAttestation | undefined> | ExecutionAttestation | undefined;
1106
- /** Package/provider/ruleset generations persisted with every newly created invocation. */
1107
- runtimeEvidence?: Partial<GovernanceRuntimeEvidence>;
1108
- /**
1109
- * Trusted composition identity attached by the Host configuration, never
1110
- * accepted directly from submission input. Requires an explicit registry;
1111
- * its module namespaces and versions are checked against these identities.
1112
- */
1113
- composition?: {
1114
- assembly: AssemblyLockfile;
1115
- /**
1116
- * Receives a fresh object whose action, scope, actor, correlation,
1117
- * causation, idempotency key, binding id and execution reason are the
1118
- * ones Host read at submission and persists, whatever the caller
1119
- * changed on its own object since. For an action without
1120
- * `admitSubmission`, its `parameters`, `provenance` and
1121
- * `authorizationBinding` read and assign the caller's input, as when
1122
- * the callback was handed that input itself; for an action that
1123
- * declares it, they are fresh copies of Host's snapshot.
1124
- */
1125
- resolveInitiatingReleaseDigest?(input: SubmitActionInput): Promise<string | undefined> | string | undefined;
1126
- };
1127
- /** Lease held while an approved invocation resumes; defaults to five minutes. */
1128
- approvalResumeLeaseDurationMs?: number;
1129
- /**
1130
- * Remove forbidden/sensitive fields before durable invocation persistence.
1131
- * For an action without `admitSubmission`, receives the caller's
1132
- * parameters object, before provenance normalization and the composition
1133
- * callback, as before. For an action that declares it, receives Host's
1134
- * copy, after the check admitted the submission.
1135
- */
1136
- redactActionParameters?: (actionId: ActionId, parameters: Record<string, unknown>) => Record<string, unknown>;
1137
- /**
1138
- * The bound on an action's `admitSubmission` check. An answer that
1139
- * settles this many milliseconds or more after the check was called,
1140
- * measured on the monotonic clock when its promise settles, is refused as
1141
- * `timed_out` and the check's signal is aborted. A whole number from 1 to
1142
- * 2 147 483 647 (the timer maximum), or `createGovernedActionHost` throws;
1143
- * default 10 000.
1144
- */
1145
- admissionTimeoutMs?: number;
1146
- resolvePolicies?: (input: ResolvePoliciesInput) => Promise<RuntimePolicyDefinition[]>;
1147
- extractEvents?: (data: Record<string, unknown>) => PendingAssetEvent[];
1148
- /** Handler-result fields consumed by extractEvents and omitted from the durable result. */
1149
- eventResultFields?: readonly string[];
1150
- redactAdapterInput?: (actionId: ActionId, adapterType: string, operation: string, input: Record<string, unknown>) => Record<string, unknown>;
1119
+ export interface ErrorTextRedactionContext {
1120
+ actionId: ActionId;
1121
+ source: "handler" | "adapter" | "external_completion" | "execution";
1122
+ adapterType?: string;
1123
+ operation?: string;
1124
+ /** Adapter vendor or external completion provider. */
1125
+ provider?: string;
1126
+ }
1127
+ export interface PlatformHostOptions<TDb> {
1128
+ store: PlatformHostStore<TDb>;
1129
+ authorization: PlatformHostAuthorization;
1130
+ /** Preferred explicit catalog assembled from this runtime's Fabric modules. */
1131
+ registry?: Pick<ModuleRegistry<TDb>, "resolveAction" | "resolvePolicy" | "resolveStateMachine"> & Partial<Pick<ModuleRegistry<TDb>, "orderedModules">>;
1132
+ /** Resolve vertical- or runtime-local actions without mutating the process-wide registry. */
1133
+ resolveAction?: (actionId: ActionId) => ActionDefinition<TDb> | undefined;
1134
+ adapters?: readonly AdapterImplementation[];
1135
+ /**
1136
+ * Supplies the circuit breaker for each adapter call. Defaults to a new
1137
+ * `AdapterCircuitBreakerRegistry` per Host instance, which creates one
1138
+ * in-process breaker per `adapterType:operation` from that adapter's own
1139
+ * `circuitBreaker` config, on first use, and none for adapters without one.
1140
+ * Pass a shared registry or a custom provider to share breakers between
1141
+ * Host instances, receive breaker telemetry, or set manual overrides.
1142
+ * The default key shares failures across tenants and vendors in a registry.
1143
+ * Use `new AdapterCircuitBreakerRegistry({ key: scopedAdapterCircuitBreakerKey })`
1144
+ * for tenant/space/vendor isolation. Host passes trusted tenant/space scope
1145
+ * to the provider. The registry keeps the first config seen for a key;
1146
+ * later conflicting configs reuse that breaker without throwing. Breakers
1147
+ * are never evicted, so scoped keys keep one breaker per scope seen.
1148
+ */
1149
+ adapterCircuitBreakers?: AdapterCircuitBreakerProvider;
1150
+ /**
1151
+ * Positive integer attempt cap for RetryableExecutionError during governance,
1152
+ * before policy-evaluation persistence (default 5). A leased, idempotent action
1153
+ * below the cap is left running for worker reclaim after lease expiry.
1154
+ * Inline execution, approval resume, exhausted attempts, and non-idempotent
1155
+ * actions fail. Policy persistence, obligation listing/resolution/persistence, state-machine checks,
1156
+ * the handler transaction, handlers, adapters, and finalization are excluded;
1157
+ * their failure/reconciliation/recovery semantics apply, subject to recoveryMaxAttempts.
1158
+ */
1159
+ retryableExecutionMaxAttempts?: number;
1160
+ /**
1161
+ * Positive integer cap on worker claims for resumed leased running invocations
1162
+ * including the first (default max(5, retryableExecutionMaxAttempts); Infinity is rejected).
1163
+ * An explicit value must be at least retryableExecutionMaxAttempts. Claims above
1164
+ * the cap settle reconciliation_required before
1165
+ * handler or adapter execution. Inline/direct execution and approval resume
1166
+ * do not increment this counter. Approval resume is admitted at the cap and settles
1167
+ * reconciliation above it; approval does not reset the count. Parked handoffs are excluded. A worker dying
1168
+ * before the check consumes a claim without executing a provider at that point.
1169
+ */
1170
+ recoveryMaxAttempts?: number;
1171
+ dispatcher?: PlatformActionDispatcher;
1172
+ services?: FabricRuntimeServices;
1173
+ idempotency?: {
1174
+ conflictMode?: "audit-only" | "enforce";
1175
+ onConflict?(conflict: IdempotencyConflict): void;
1176
+ onLegacyRecord?(invocation: ActionInvocationRecord): void;
1177
+ };
1178
+ provenance?: {
1179
+ auditAttributeAllowlist?: readonly string[];
1180
+ maxAttributes?: number;
1181
+ maxValueLength?: number;
1182
+ redactAuditAttributes?(attributes: NamespacedAttributes): NamespacedAttributes;
1183
+ onTrace?(provenance: InvocationProvenance): void;
1184
+ };
1185
+ /** Requires an outbox-capable store; every canonical event is then appended with delivery state. */
1186
+ outbox?: {
1187
+ producerModuleVersion(actionId: ActionId, actionVersion: number): string;
1188
+ classifyPayload(event: AssetEventEnvelope): EventPayloadClassification;
1189
+ includeProvenance?(event: AssetEventEnvelope, classification: EventPayloadClassification): boolean;
1151
1190
  /**
1152
- * Redact successful adapter output before row/event persistence and attestation extraction.
1153
- * A throwing hook or a null, array or non-object return withholds output and requires reconciliation.
1154
- * Class instances and Dates are accepted, matching the adapter output record contract.
1155
- * Keep redactors deterministic and stable across deploys.
1156
- * Accepted-operation references are read from the original adapter result.
1191
+ * Opt an event's `actorId` and `actorType` into its outbox envelope. Absent, the actor is
1192
+ * excluded for every classification. Only `true` includes it. An included actor reaches every
1193
+ * sink of every relay reading this outbox.
1157
1194
  */
1158
- redactAdapterOutput?: (actionId: ActionId, adapterType: string, operation: string, output: Record<string, unknown>) => Record<string, unknown>;
1159
- /**
1160
- * Redact originating handler, adapter, completion and caught execution error text.
1161
- * Host-authored fixed text bypasses this hook; circuit and consistency errors use adapter context.
1162
- * Empty originating text bypasses the hook unchanged. For non-empty input, throwing or returning
1163
- * a non-string or empty string uses a placeholder on execution paths, but refuses a completion
1164
- * as redaction_failed before writes. State-machine `transition.error` text uses `source: "handler"`.
1165
- * Keep redactors deterministic and stable across deploys: changed output can make a repeat
1166
- * completion look like different evidence.
1167
- */
1168
- redactErrorText?: (context: ErrorTextRedactionContext, message: string) => string;
1169
- /**
1170
- * Redact completion results before merging, schema validation, persistence and digesting.
1171
- * Contradiction detection compares retained values; legacy raw digests also match repeats.
1172
- * A throwing hook or a null, array or non-object return refuses as redaction_failed before writes.
1173
- * Class instances and Dates are accepted by the same record predicate as adapter output.
1174
- * Keep redactors deterministic and stable across deploys: changes can make a repeat look like
1175
- * different evidence. A matching legacy raw digest is acknowledged before invoking hooks.
1176
- */
1177
- redactExternalCompletionResult?: (actionId: ActionId, provider: string, result: Record<string, unknown>) => Record<string, unknown>;
1178
- adapterEventSubject?: (actionId: ActionId, parameters: unknown, handlerResult: Record<string, unknown>) => {
1179
- subjectType: string;
1180
- subjectId: string;
1181
- } | undefined;
1182
- now?: () => Date;
1183
- /** Vendor-neutral lifecycle and metric sink. Telemetry is best effort. */
1184
- telemetry?: PlatformHostTelemetry;
1185
- /**
1186
- * Epoch-millis deadline delivered to every adapter execution context.
1187
- * When omitted, no deadline is set and adapters receive no AbortSignal.
1188
- */
1189
- adapterDeadlineMs?: number;
1190
- }
1191
- interface GovernedActionHost {
1192
- submitAction(input: SubmitActionInput): Promise<SubmitActionResult>;
1193
- executeInvocation(actionInvocationId: string, tenantId: string, spaceId: string, options?: ExecuteInvocationOptions): Promise<ExecuteActionResult>;
1194
- resumeApprovedInvocation(actionInvocationId: string, tenantId: string, spaceId: string, decision: ActionApprovalDecision): Promise<ExecuteActionResult>;
1195
- recordExecutionAttestation(actionInvocationId: string, tenantId: string, spaceId: string, attestation: ExecutionAttestation): Promise<void>;
1196
- recordExternalReconciliation(actionInvocationId: string, tenantId: string, spaceId: string, reconciliation: ExternalReconciliation): Promise<void>;
1197
- /**
1198
- * Complete an invocation an adapter handed off, by the reference the
1199
- * external system was given. Idempotent for a repeated identical
1200
- * completion; a contradictory one moves the invocation to reconciliation.
1201
- */
1202
- completeExternalInvocation(actionInvocationId: string, tenantId: string, spaceId: string, completion: ExternalCompletion): Promise<ExecuteActionResult>;
1195
+ includeActor?(event: AssetEventEnvelope, classification: EventPayloadClassification): boolean;
1196
+ traceContext?(event: AssetEventEnvelope): Record<string, string> | undefined;
1197
+ /** Host lifecycle events are excluded by default; opt in only after making their payload audit-safe. */
1198
+ shouldPublish?(event: AssetEventEnvelope): boolean;
1199
+ };
1200
+ /** Optional vertical-owned evaluator. When absent, agent behavior is unchanged. */
1201
+ hitlEvaluator?: AgentActionPolicyEvaluator;
1202
+ /** Durable evaluator/ruleset version recorded with every HITL decision. */
1203
+ hitlPolicyVersion?: string;
1204
+ /** Optional portable resolver; provider-specific implementations belong in integration packages. */
1205
+ resolveMutationGovernance?: MutationGovernanceResolver;
1206
+ /** Translate policy outcomes into durable, enforceable obligations. */
1207
+ resolvePolicyObligations?: (outcomes: readonly PolicyOutcome[]) => Promise<PolicyObligation[]> | PolicyObligation[];
1208
+ /** Translate a successful adapter result into audit-safe evidence. Recovery may call this
1209
+ * again with stored input/output; return deterministic evidence for the same input. */
1210
+ extractExecutionAttestation?: (input: {
1211
+ actionInvocationId: string;
1212
+ adapterInvocationId: string;
1213
+ adapterType: string;
1214
+ operation: string;
1215
+ vendor: string;
1216
+ /** Audit-safe adapter input after redactAdapterInput has been applied. */
1217
+ input: Record<string, unknown>;
1218
+ startedAt: Date;
1219
+ completedAt: Date;
1220
+ /** Adapter output after redactAdapterOutput, when configured. */
1221
+ output: Record<string, unknown>;
1222
+ }) => Promise<ExecutionAttestation | undefined> | ExecutionAttestation | undefined;
1223
+ /** Package/provider/ruleset generations persisted with every newly created invocation. */
1224
+ runtimeEvidence?: Partial<GovernanceRuntimeEvidence>;
1225
+ /**
1226
+ * Trusted composition identity attached by the Host configuration, never
1227
+ * accepted directly from submission input. Requires an explicit registry;
1228
+ * its module namespaces and versions are checked against these identities.
1229
+ */
1230
+ composition?: {
1231
+ assembly: AssemblyLockfile;
1203
1232
  /**
1204
- * Move handoffs past their deadline to `reconciliation_required`, so a
1205
- * callback that never comes is a finding and not a silent wait. The
1206
- * pending handoff is kept, so a late completion can still land.
1233
+ * Receives a fresh object whose action, scope, actor, correlation,
1234
+ * causation, idempotency key, binding id and execution reason are the
1235
+ * ones Host read at submission and persists, whatever the caller
1236
+ * changed on its own object since. For an action without
1237
+ * `admitSubmission`, its `parameters`, `provenance` and
1238
+ * `authorizationBinding` read and assign the caller's input, as when
1239
+ * the callback was handed that input itself; for an action that
1240
+ * declares it, they are fresh copies of Host's snapshot.
1207
1241
  */
1208
- reconcileOverdueCompletions(input?: ReconcileOverdueCompletionsInput): Promise<{
1209
- overdue: string[];
1210
- }>;
1242
+ resolveInitiatingReleaseDigest?(input: SubmitActionInput): Promise<string | undefined> | string | undefined;
1243
+ };
1244
+ /** Lease held while an approved invocation resumes; defaults to five minutes. */
1245
+ approvalResumeLeaseDurationMs?: number;
1246
+ /**
1247
+ * Remove forbidden/sensitive fields before durable invocation persistence.
1248
+ * For an action without `admitSubmission`, receives the caller's
1249
+ * parameters object, before provenance normalization and the composition
1250
+ * callback, as before. For an action that declares it, receives Host's
1251
+ * copy, after the check admitted the submission.
1252
+ */
1253
+ redactActionParameters?: (actionId: ActionId, parameters: Record<string, unknown>) => Record<string, unknown>;
1254
+ /**
1255
+ * The bound on an action's `admitSubmission` check. An answer that
1256
+ * settles this many milliseconds or more after the check was called,
1257
+ * measured on the monotonic clock when its promise settles, is refused as
1258
+ * `timed_out` and the check's signal is aborted. A whole number from 1 to
1259
+ * 2 147 483 647 (the timer maximum), or `createGovernedActionHost` throws;
1260
+ * default 10 000.
1261
+ */
1262
+ admissionTimeoutMs?: number;
1263
+ resolvePolicies?: (input: ResolvePoliciesInput) => Promise<RuntimePolicyDefinition[]>;
1264
+ extractEvents?: (data: Record<string, unknown>) => PendingAssetEvent[];
1265
+ /** Handler-result fields consumed by extractEvents and omitted from the durable result. */
1266
+ eventResultFields?: readonly string[];
1267
+ redactAdapterInput?: (actionId: ActionId, adapterType: string, operation: string, input: Record<string, unknown>) => Record<string, unknown>;
1268
+ /**
1269
+ * Redact successful adapter output before row/event persistence and attestation extraction.
1270
+ * A throwing hook or a null, array or non-object return withholds output and requires reconciliation.
1271
+ * Class instances and Dates are accepted, matching the adapter output record contract.
1272
+ * Keep redactors deterministic and stable across deploys.
1273
+ * Accepted-operation references are read from the original adapter result.
1274
+ */
1275
+ redactAdapterOutput?: (actionId: ActionId, adapterType: string, operation: string, output: Record<string, unknown>) => Record<string, unknown>;
1276
+ /**
1277
+ * Redact originating handler, adapter, completion and caught execution error text.
1278
+ * Host-authored fixed text bypasses this hook; circuit and consistency errors use adapter context.
1279
+ * Empty originating text bypasses the hook unchanged. For non-empty input, throwing or returning
1280
+ * a non-string or empty string uses a placeholder on execution paths, but refuses a completion
1281
+ * as redaction_failed before writes. State-machine `transition.error` text uses `source: "handler"`.
1282
+ * Keep redactors deterministic and stable across deploys: changed output can make a repeat
1283
+ * completion look like different evidence.
1284
+ */
1285
+ redactErrorText?: (context: ErrorTextRedactionContext, message: string) => string;
1286
+ /**
1287
+ * Redact completion results before merging, schema validation, persistence and digesting.
1288
+ * Contradiction detection compares retained values; legacy raw digests also match repeats.
1289
+ * A throwing hook or a null, array or non-object return refuses as redaction_failed before writes.
1290
+ * Class instances and Dates are accepted by the same record predicate as adapter output.
1291
+ * Keep redactors deterministic and stable across deploys: changes can make a repeat look like
1292
+ * different evidence. A matching legacy raw digest is acknowledged before invoking hooks.
1293
+ */
1294
+ redactExternalCompletionResult?: (actionId: ActionId, provider: string, result: Record<string, unknown>) => Record<string, unknown>;
1295
+ adapterEventSubject?: (actionId: ActionId, parameters: unknown, handlerResult: Record<string, unknown>) => {
1296
+ subjectType: string;
1297
+ subjectId: string;
1298
+ } | undefined;
1299
+ now?: () => Date;
1300
+ /** Vendor-neutral lifecycle and metric sink. Telemetry is best effort. */
1301
+ telemetry?: PlatformHostTelemetry;
1302
+ /**
1303
+ * Epoch-millis deadline delivered to every adapter execution context.
1304
+ * When omitted, no deadline is set and adapters receive no AbortSignal.
1305
+ */
1306
+ adapterDeadlineMs?: number;
1307
+ }
1308
+ export interface GovernedActionHost {
1309
+ submitAction(input: SubmitActionInput): Promise<SubmitActionResult>;
1310
+ executeInvocation(actionInvocationId: string, tenantId: string, spaceId: string, options?: ExecuteInvocationOptions): Promise<ExecuteActionResult>;
1311
+ resumeApprovedInvocation(actionInvocationId: string, tenantId: string, spaceId: string, decision: ActionApprovalDecision): Promise<ExecuteActionResult>;
1312
+ recordExecutionAttestation(actionInvocationId: string, tenantId: string, spaceId: string, attestation: ExecutionAttestation): Promise<void>;
1313
+ recordExternalReconciliation(actionInvocationId: string, tenantId: string, spaceId: string, reconciliation: ExternalReconciliation): Promise<void>;
1314
+ /**
1315
+ * Complete an invocation an adapter handed off, by the reference the
1316
+ * external system was given. Idempotent for a repeated identical
1317
+ * completion; a contradictory one moves the invocation to reconciliation.
1318
+ */
1319
+ completeExternalInvocation(actionInvocationId: string, tenantId: string, spaceId: string, completion: ExternalCompletion): Promise<ExecuteActionResult>;
1320
+ /**
1321
+ * Move eligible running, unleased overdue handoffs to `reconciliation_required`
1322
+ * and retain the handoff with overdueAt. A callback can settle that verdict
1323
+ * only after parking; callbacks for swept unparked invocations record redacted
1324
+ * evidence without result-schema validation. Parked rows lacking overdueAt
1325
+ * retain the weaker "did not complete by" error-substring fallback.
1326
+ */
1327
+ reconcileOverdueCompletions(input?: ReconcileOverdueCompletionsInput): Promise<{
1328
+ overdue: string[];
1329
+ }>;
1211
1330
  }
1212
1331
  /**
1213
1332
  * Host operator operations kept outside `GovernedActionHost`, so an existing
1214
1333
  * hand-written `GovernedActionHost` still satisfies that interface.
1215
1334
  * `createGovernedActionHost()` returns both.
1216
1335
  */
1217
- interface OutboxRequeueHost {
1218
- /**
1219
- * Operator replay of a dead-lettered outbox record: authorize the trusted
1220
- * actor for the tenant and space against the record as read, then move
1221
- * that same dead letter back to pending with a fresh attempt budget and
1222
- * append who, when, and why beside the earlier failure. The relay
1223
- * republishes it under the same `eventId`. Requires an
1224
- * `OutboxRequeuePlatformHostStore`; refusals are returned, not thrown.
1225
- */
1226
- requeueOutboxDeadLetter(input: RequeueOutboxDeadLetterInput): Promise<RequeueOutboxDeadLetterResult>;
1227
- }
1228
-
1229
- declare function createGovernedActionHost<TDb>(options: PlatformHostOptions<TDb>): GovernedActionHost & OutboxRequeueHost;
1230
-
1231
- interface MemoryPlatformHostTransactionProvider<TDb> {
1232
- snapshot(db: TDb): TDb;
1233
- restore(db: TDb, snapshot: TDb): void;
1234
- }
1235
- declare class MemoryPlatformHostStore<TDb> implements RecoverablePlatformHostStore<TDb>, ApprovalPlatformHostStore<TDb>, GovernancePlatformHostStore<TDb>, OutboxPlatformHostStore<TDb>, OutboxRequeuePlatformHostStore<TDb> {
1236
- readonly db: TDb;
1237
- readonly transactionalOutbox: boolean;
1238
- transactionWithEvents?: <TResult>(run: (transaction: PlatformHostMutationTransaction<TDb>) => Promise<TResult>) => Promise<TResult>;
1239
- private transactionTail;
1240
- readonly invocations: ActionInvocationRecord[];
1241
- readonly policyEvaluations: PolicyEvaluationRecord[];
1242
- readonly adapterInvocations: AdapterInvocationRecord[];
1243
- readonly events: AssetEventEnvelope[];
1244
- readonly policyObligations: PolicyObligationRecord[];
1245
- readonly executionAttestations: ExecutionAttestationRecord[];
1246
- readonly externalReconciliations: ExternalReconciliationRecord[];
1247
- readonly outbox: OutboxRecord[];
1248
- /**
1249
- * Requeue evidence is append-only audit history, so unlike the ledger
1250
- * arrays above, which tests have always inspected and seeded directly, it
1251
- * is not public: `listOutboxRequeues` returns copies with their own Dates. TypeScript
1252
- * `private`, as for the store's other internals, is a compile-time guard.
1253
- */
1254
- private readonly outboxRequeues;
1255
- constructor(db: TDb, transactionProvider?: MemoryPlatformHostTransactionProvider<TDb>);
1256
- transaction<TResult>(run: (db: TDb) => Promise<TResult>): Promise<TResult>;
1257
- private runTransactionWithEvents;
1258
- createActionInvocation(input: CreateActionInvocationInput): Promise<ActionInvocationRecord>;
1259
- getActionInvocation(id: string, tenantId: string, spaceId: string): Promise<ActionInvocationRecord | undefined>;
1260
- updateActionInvocation(id: string, tenantId: string, spaceId: string, patch: ActionInvocationPatch): Promise<void>;
1261
- recordHitlDecision(actionInvocationId: string, tenantId: string, spaceId: string, decision: HitlDecisionEvidence): Promise<ActionInvocationRecord>;
1262
- beginApprovalDecision(input: BeginApprovalDecisionInput): Promise<ApprovalDecisionTransitionResult>;
1263
- appendPolicyEvaluation(record: PolicyEvaluationRecord): Promise<void>;
1264
- recordMutationGovernance(actionInvocationId: string, tenantId: string, spaceId: string, context: Pick<ActionInvocationRecord, "mutationFootprint" | "executionPrincipal"> & {
1265
- footprint: NonNullable<ActionInvocationRecord["mutationFootprint"]>;
1266
- executionPrincipal: NonNullable<ActionInvocationRecord["executionPrincipal"]>;
1267
- }): Promise<ActionInvocationRecord>;
1268
- appendPolicyObligations(records: PolicyObligationRecord[]): Promise<void>;
1269
- listPolicyObligations(actionInvocationId: string, tenantId: string, spaceId: string): Promise<PolicyObligationRecord[]>;
1270
- updatePolicyObligation(actionInvocationId: string, obligationId: string, status: PolicyObligationRecord["status"], evidenceReferences?: PolicyObligationRecord["evidenceReferences"]): Promise<void>;
1271
- appendExecutionAttestation(record: ExecutionAttestationRecord): Promise<void>;
1272
- listExecutionAttestations(actionInvocationId: string, tenantId: string, spaceId: string): Promise<ExecutionAttestationRecord[]>;
1273
- appendExternalReconciliation(record: ExternalReconciliationRecord): Promise<void>;
1274
- createAdapterInvocation(record: AdapterInvocationRecord): Promise<void>;
1275
- getAdapterInvocation(id: string, scope?: AdapterInvocationScope): Promise<AdapterInvocationRecord | undefined>;
1276
- updateAdapterInvocation(id: string, patch: Partial<Pick<AdapterInvocationRecord, "status" | "output" | "error" | "attempt" | "updatedAt">>, scope?: AdapterInvocationScope): Promise<void>;
1277
- appendEvent(event: AssetEventEnvelope): Promise<void>;
1278
- appendEventWithOutbox(event: AssetEventEnvelope, metadata: OutboxEventMetadata): Promise<void>;
1279
- claimOutbox(input: ClaimOutboxInput): Promise<OutboxRecord[]>;
1280
- markOutboxPublished(id: string, workerId: string, publishedAt: Date, leaseToken?: number): Promise<void>;
1281
- markOutboxFailed(input: {
1282
- id: string;
1283
- workerId: string;
1284
- leaseToken?: number;
1285
- error: string;
1286
- availableAt: Date;
1287
- deadLetter: boolean;
1288
- }): Promise<void>;
1289
- renewOutboxLease(input: {
1290
- id: string;
1291
- workerId: string;
1292
- leaseToken: number;
1293
- leaseDurationMs: number;
1294
- now?: Date;
1295
- }): Promise<boolean>;
1296
- listOutbox(input?: {
1297
- tenantId?: string;
1298
- spaceId?: string;
1299
- statuses?: OutboxStatus[];
1300
- }): Promise<OutboxRecord[]>;
1301
- getOutboxRecord(id: string, tenantId: string, spaceId: string): Promise<OutboxRecord | undefined>;
1302
- requeueOutboxDeadLetter(input: RequeueOutboxDeadLetterStoreInput): Promise<RequeueOutboxDeadLetterStoreResult>;
1303
- listOutboxRequeues(input: {
1304
- tenantId: string;
1305
- spaceId: string;
1306
- outboxId?: string;
1307
- }): Promise<OutboxRequeueRecord[]>;
1308
- private requireLeasedOutbox;
1309
- nextEventSequence(tenantId: string, spaceId: string): Promise<number>;
1310
- getEntityStateSource(tenantId: string, spaceId: string, entityType: string, entityId: string): Promise<{
1311
- state: string;
1312
- actionInvocationId: string;
1313
- } | undefined>;
1314
- getEntityState(tenantId: string, spaceId: string, entityType: string, entityId: string): Promise<string | undefined>;
1315
- listActionInvocations(input?: ListActionInvocationsInput): Promise<ActionInvocationRecord[]>;
1316
- getHealthCounts(input: PlatformHostHealthQuery): Promise<PlatformHostHealthCounts>;
1317
- claimActionInvocations(input: ClaimActionInvocationsInput): Promise<ActionInvocationRecord[]>;
1318
- updateLeasedActionInvocation(input: UpdateLeasedActionInvocationInput): Promise<boolean>;
1319
- renewActionInvocationLease(input: RenewActionInvocationLeaseInput): Promise<boolean>;
1320
- listEvents(tenantId: string, spaceId: string): Promise<AssetEventEnvelope[]>;
1321
- }
1322
-
1323
- declare function toEnterpriseEventEnvelope(event: AssetEventEnvelope, metadata: OutboxEventMetadata): EnterpriseEventEnvelope;
1324
- /** The `includeActor` decision a store records with the outbox record it writes from `metadata`. */
1325
- declare function outboxActorDisclosure(metadata: OutboxEventMetadata): OutboxActorDisclosure;
1326
- interface EnterpriseEventPublishContext {
1327
- signal: AbortSignal;
1328
- /**
1329
- * Why the envelope does or does not carry `actorId`/`actorType`. `runOutboxRelayCycle()` always
1330
- * sets it; a caller other than the relay may omit it, which a consumer should treat like `legacy`.
1331
- */
1332
- actorDisclosure?: EnterpriseEventActorDisclosure;
1333
- }
1334
- interface EnterpriseEventPublisher {
1335
- publish(event: EnterpriseEventEnvelope, context?: EnterpriseEventPublishContext): Promise<void>;
1336
- }
1337
- interface OutboxRelayOptions<TDb> {
1338
- store: OutboxPlatformHostStore<TDb>;
1339
- publisher: EnterpriseEventPublisher;
1336
+ export interface OutboxRequeueHost {
1337
+ /**
1338
+ * Operator replay of a dead-lettered outbox record: authorize the trusted
1339
+ * actor for the tenant and space against the record as read, then move
1340
+ * that same dead letter back to pending with a fresh attempt budget and
1341
+ * append who, when, and why beside the earlier failure. The relay
1342
+ * republishes it under the same `eventId`. Requires an
1343
+ * `OutboxRequeuePlatformHostStore`; refusals are returned, not thrown.
1344
+ */
1345
+ requeueOutboxDeadLetter(input: RequeueOutboxDeadLetterInput): Promise<RequeueOutboxDeadLetterResult>;
1346
+ }
1347
+ //#endregion
1348
+ //#region src/host.d.ts
1349
+ export declare function createGovernedActionHost<TDb>(options: PlatformHostOptions<TDb>): GovernedActionHost & OutboxRequeueHost;
1350
+ //#endregion
1351
+ //#region src/memory-store.d.ts
1352
+ export interface MemoryPlatformHostTransactionProvider<TDb> {
1353
+ snapshot(db: TDb): TDb;
1354
+ restore(db: TDb, snapshot: TDb): void;
1355
+ }
1356
+ export declare class MemoryPlatformHostStore<TDb> implements RecoverablePlatformHostStore<TDb>, ApprovalPlatformHostStore<TDb>, GovernancePlatformHostStore<TDb>, OutboxPlatformHostStore<TDb>, OutboxRequeuePlatformHostStore<TDb> {
1357
+ readonly db: TDb;
1358
+ readonly transactionalOutbox: boolean;
1359
+ transactionWithEvents?: <TResult>(run: (transaction: PlatformHostMutationTransaction<TDb>) => Promise<TResult>) => Promise<TResult>;
1360
+ private adapterCommit;
1361
+ private transactionTail;
1362
+ readonly invocations: ActionInvocationRecord[];
1363
+ readonly policyEvaluations: PolicyEvaluationRecord[];
1364
+ readonly adapterInvocations: AdapterInvocationRecord[];
1365
+ readonly events: AssetEventEnvelope[];
1366
+ readonly policyObligations: PolicyObligationRecord[];
1367
+ readonly executionAttestations: ExecutionAttestationRecord[];
1368
+ readonly externalReconciliations: ExternalReconciliationRecord[];
1369
+ readonly outbox: OutboxRecord[];
1370
+ /**
1371
+ * Requeue evidence is append-only audit history, so unlike the ledger
1372
+ * arrays above, which tests have always inspected and seeded directly, it
1373
+ * is not public: `listOutboxRequeues` returns copies with their own Dates. TypeScript
1374
+ * `private`, as for the store's other internals, is a compile-time guard.
1375
+ */
1376
+ private readonly outboxRequeues;
1377
+ constructor(db: TDb, transactionProvider?: MemoryPlatformHostTransactionProvider<TDb>);
1378
+ transaction<TResult>(run: (db: TDb) => Promise<TResult>): Promise<TResult>;
1379
+ private runTransactionWithEvents;
1380
+ createActionInvocation(input: CreateActionInvocationInput): Promise<ActionInvocationRecord>;
1381
+ getActionInvocation(id: string, tenantId: string, spaceId: string): Promise<ActionInvocationRecord | undefined>;
1382
+ updateActionInvocation(id: string, tenantId: string, spaceId: string, patch: ActionInvocationPatch): Promise<void>;
1383
+ recordHitlDecision(actionInvocationId: string, tenantId: string, spaceId: string, decision: HitlDecisionEvidence): Promise<ActionInvocationRecord>;
1384
+ beginApprovalDecision(input: BeginApprovalDecisionInput): Promise<ApprovalDecisionTransitionResult>;
1385
+ appendPolicyEvaluation(record: PolicyEvaluationRecord): Promise<void>;
1386
+ recordMutationGovernance(actionInvocationId: string, tenantId: string, spaceId: string, context: Pick<ActionInvocationRecord, "mutationFootprint" | "executionPrincipal"> & {
1387
+ footprint: NonNullable<ActionInvocationRecord["mutationFootprint"]>;
1388
+ executionPrincipal: NonNullable<ActionInvocationRecord["executionPrincipal"]>;
1389
+ }): Promise<ActionInvocationRecord>;
1390
+ appendPolicyObligations(records: PolicyObligationRecord[]): Promise<void>;
1391
+ listPolicyObligations(actionInvocationId: string, tenantId: string, spaceId: string): Promise<PolicyObligationRecord[]>;
1392
+ updatePolicyObligation(actionInvocationId: string, obligationId: string, status: PolicyObligationRecord["status"], evidenceReferences?: PolicyObligationRecord["evidenceReferences"]): Promise<void>;
1393
+ appendExecutionAttestation(record: ExecutionAttestationRecord): Promise<void>;
1394
+ listExecutionAttestations(actionInvocationId: string, tenantId: string, spaceId: string): Promise<ExecutionAttestationRecord[]>;
1395
+ appendExternalReconciliation(record: ExternalReconciliationRecord): Promise<void>;
1396
+ private adapterWriteMatches;
1397
+ updateSettledActionInvocation(input: UpdateSettledActionInvocationInput): Promise<boolean>;
1398
+ writeAdapterInvocation(input: AdapterInvocationWriteInput): Promise<boolean>;
1399
+ createAdapterInvocation(record: AdapterInvocationRecord): Promise<void>;
1400
+ getAdapterInvocation(id: string, scope?: AdapterInvocationScope): Promise<AdapterInvocationRecord | undefined>;
1401
+ updateAdapterInvocation(id: string, patch: Partial<Pick<AdapterInvocationRecord, "status" | "output" | "error" | "attempt" | "updatedAt" | "reconciliation">>, scope?: AdapterInvocationScope): Promise<void>;
1402
+ appendEvent(event: AssetEventEnvelope): Promise<void>;
1403
+ appendEventWithOutbox(event: AssetEventEnvelope, metadata: OutboxEventMetadata): Promise<void>;
1404
+ claimOutbox(input: ClaimOutboxInput): Promise<OutboxRecord[]>;
1405
+ markOutboxPublished(id: string, workerId: string, publishedAt: Date, leaseToken?: number): Promise<void>;
1406
+ markOutboxFailed(input: {
1407
+ id: string;
1408
+ workerId: string;
1409
+ leaseToken?: number;
1410
+ error: string;
1411
+ availableAt: Date;
1412
+ deadLetter: boolean;
1413
+ }): Promise<void>;
1414
+ renewOutboxLease(input: {
1415
+ id: string;
1340
1416
  workerId: string;
1341
- leaseDurationMs?: number;
1342
- leaseRenewalIntervalMs?: number;
1343
- publishTimeoutMs?: number;
1344
- batchSize?: number;
1345
- maxAttempts?: number;
1346
- retryDelayMs?: (attempt: number) => number;
1347
- now?: () => Date;
1348
- telemetry?: PlatformHostTelemetry;
1349
- }
1350
- interface OutboxRelayResult {
1351
- claimed: number;
1352
- published: number;
1353
- failed: number;
1354
- deadLettered: number;
1355
- }
1356
- declare function runOutboxRelayCycle<TDb>(options: OutboxRelayOptions<TDb>): Promise<OutboxRelayResult>;
1417
+ leaseToken: number;
1418
+ leaseDurationMs: number;
1419
+ now?: Date;
1420
+ }): Promise<boolean>;
1421
+ listOutbox(input?: {
1422
+ tenantId?: string;
1423
+ spaceId?: string;
1424
+ statuses?: OutboxStatus[];
1425
+ }): Promise<OutboxRecord[]>;
1426
+ getOutboxRecord(id: string, tenantId: string, spaceId: string): Promise<OutboxRecord | undefined>;
1427
+ requeueOutboxDeadLetter(input: RequeueOutboxDeadLetterStoreInput): Promise<RequeueOutboxDeadLetterStoreResult>;
1428
+ listOutboxRequeues(input: {
1429
+ tenantId: string;
1430
+ spaceId: string;
1431
+ outboxId?: string;
1432
+ }): Promise<OutboxRequeueRecord[]>;
1433
+ private requireLeasedOutbox;
1434
+ nextEventSequence(tenantId: string, spaceId: string): Promise<number>;
1435
+ getEntityStateSource(tenantId: string, spaceId: string, entityType: string, entityId: string): Promise<{
1436
+ state: string;
1437
+ actionInvocationId: string;
1438
+ } | undefined>;
1439
+ getEntityState(tenantId: string, spaceId: string, entityType: string, entityId: string): Promise<string | undefined>;
1440
+ listActionInvocations(input?: ListActionInvocationsInput): Promise<ActionInvocationRecord[]>;
1441
+ getHealthCounts(input: PlatformHostHealthQuery): Promise<PlatformHostHealthCounts>;
1442
+ claimActionInvocations(input: ClaimActionInvocationsInput): Promise<ActionInvocationRecord[]>;
1443
+ updateLeasedActionInvocation(input: UpdateLeasedActionInvocationInput): Promise<boolean>;
1444
+ renewActionInvocationLease(input: RenewActionInvocationLeaseInput): Promise<boolean>;
1445
+ listEvents(tenantId: string, spaceId: string): Promise<AssetEventEnvelope[]>;
1446
+ }
1447
+ //#endregion
1448
+ //#region src/outbox.d.ts
1449
+ export declare function toEnterpriseEventEnvelope(event: AssetEventEnvelope, metadata: OutboxEventMetadata): EnterpriseEventEnvelope;
1450
+ /** The `includeActor` decision a store records with the outbox record it writes from `metadata`. */
1451
+ export declare function outboxActorDisclosure(metadata: OutboxEventMetadata): OutboxActorDisclosure;
1452
+ export interface EnterpriseEventPublishContext {
1453
+ signal: AbortSignal;
1454
+ /**
1455
+ * Why the envelope does or does not carry `actorId`/`actorType`. `runOutboxRelayCycle()` always
1456
+ * sets it; a caller other than the relay may omit it, which a consumer should treat like `legacy`.
1457
+ */
1458
+ actorDisclosure?: EnterpriseEventActorDisclosure;
1459
+ }
1460
+ export interface EnterpriseEventPublisher {
1461
+ publish(event: EnterpriseEventEnvelope, context?: EnterpriseEventPublishContext): Promise<void>;
1462
+ }
1463
+ export interface OutboxRelayOptions<TDb> {
1464
+ store: OutboxPlatformHostStore<TDb>;
1465
+ publisher: EnterpriseEventPublisher;
1466
+ workerId: string;
1467
+ leaseDurationMs?: number;
1468
+ leaseRenewalIntervalMs?: number;
1469
+ publishTimeoutMs?: number;
1470
+ batchSize?: number;
1471
+ maxAttempts?: number;
1472
+ retryDelayMs?: (attempt: number) => number;
1473
+ now?: () => Date;
1474
+ telemetry?: PlatformHostTelemetry;
1475
+ }
1476
+ export interface OutboxRelayResult {
1477
+ claimed: number;
1478
+ published: number;
1479
+ failed: number;
1480
+ deadLettered: number;
1481
+ }
1482
+ export declare function runOutboxRelayCycle<TDb>(options: OutboxRelayOptions<TDb>): Promise<OutboxRelayResult>;
1357
1483
  /**
1358
1484
  * A copy with its own Date fields and trace context. The event payload and
1359
1485
  * provenance are shallow: the copy shares them with the record, as before.
1360
1486
  */
1361
- declare function cloneOutboxRecord(record: OutboxRecord): OutboxRecord;
1362
-
1363
- interface PlatformHostSqlResult<Row = Record<string, unknown>> {
1364
- rows: Row[];
1487
+ export declare function cloneOutboxRecord(record: OutboxRecord): OutboxRecord;
1488
+ //#endregion
1489
+ //#region src/postgres-store.d.ts
1490
+ export interface PlatformHostSqlResult<Row = Record<string, unknown>> {
1491
+ rows: Row[];
1365
1492
  }
1366
1493
  /** Structural subset implemented by `pg.Pool` and Lakebase-compatible clients. */
1367
- interface PlatformHostSqlClient {
1368
- query<Row = Record<string, unknown>>(sql: string, values?: unknown[]): Promise<PlatformHostSqlResult<Row>>;
1494
+ export interface PlatformHostSqlClient {
1495
+ query<Row = Record<string, unknown>>(sql: string, values?: unknown[]): Promise<PlatformHostSqlResult<Row>>;
1369
1496
  }
1370
- interface PostgresPlatformHostTransactionContext<TDb> {
1371
- db: TDb;
1372
- sql: PlatformHostSqlClient;
1497
+ export interface PostgresPlatformHostTransactionContext<TDb> {
1498
+ db: TDb;
1499
+ sql: PlatformHostSqlClient;
1373
1500
  }
1374
1501
  /**
1375
1502
  * Application-owned transaction binder.
@@ -1378,87 +1505,90 @@ interface PostgresPlatformHostTransactionContext<TDb> {
1378
1505
  * `pg.PoolClient`. Production applications provide this adapter so domain
1379
1506
  * methods and Host ledger writes share one PostgreSQL transaction.
1380
1507
  */
1381
- interface PostgresPlatformHostTransactionProvider<TDb> {
1382
- run<TResult>(run: (context: PostgresPlatformHostTransactionContext<TDb>) => Promise<TResult>): Promise<TResult>;
1508
+ export interface PostgresPlatformHostTransactionProvider<TDb> {
1509
+ run<TResult>(run: (context: PostgresPlatformHostTransactionContext<TDb>) => Promise<TResult>): Promise<TResult>;
1383
1510
  }
1384
1511
  /** Durable mutation-pipeline ledger for Databricks Lakebase or standard Postgres. */
1385
- declare class PostgresPlatformHostStore<TDb> implements RecoverablePlatformHostStore<TDb>, ApprovalPlatformHostStore<TDb>, GovernancePlatformHostStore<TDb>, OutboxPlatformHostStore<TDb>, OutboxRequeuePlatformHostStore<TDb> {
1386
- readonly db: TDb;
1387
- private readonly sql;
1388
- readonly transactionWithEvents?: AtomicMutationPlatformHostStore<TDb>["transactionWithEvents"];
1389
- readonly transactionalOutbox: boolean;
1390
- constructor(db: TDb, sql: PlatformHostSqlClient, transactionProvider?: PostgresPlatformHostTransactionProvider<TDb>);
1391
- ensureSchema(): Promise<void>;
1392
- transaction<TResult>(run: (db: TDb) => Promise<TResult>): Promise<TResult>;
1393
- createActionInvocation(input: CreateActionInvocationInput): Promise<ActionInvocationRecord>;
1394
- getActionInvocation(id: string, tenantId: string, spaceId: string): Promise<ActionInvocationRecord | undefined>;
1395
- updateActionInvocation(id: string, tenantId: string, spaceId: string, patch: ActionInvocationPatch): Promise<void>;
1396
- recordHitlDecision(actionInvocationId: string, tenantId: string, spaceId: string, decision: HitlDecisionEvidence): Promise<ActionInvocationRecord>;
1397
- beginApprovalDecision(input: BeginApprovalDecisionInput): Promise<ApprovalDecisionTransitionResult>;
1398
- appendPolicyEvaluation(record: PolicyEvaluationRecord): Promise<void>;
1399
- recordMutationGovernance(actionInvocationId: string, tenantId: string, spaceId: string, context: {
1400
- footprint: NonNullable<ActionInvocationRecord["mutationFootprint"]>;
1401
- executionPrincipal: NonNullable<ActionInvocationRecord["executionPrincipal"]>;
1402
- }): Promise<ActionInvocationRecord>;
1403
- appendPolicyObligations(records: PolicyObligationRecord[]): Promise<void>;
1404
- listPolicyObligations(actionInvocationId: string, tenantId: string, spaceId: string): Promise<PolicyObligationRecord[]>;
1405
- updatePolicyObligation(actionInvocationId: string, obligationId: string, status: PolicyObligationRecord["status"], evidenceReferences?: PolicyObligationRecord["evidenceReferences"]): Promise<void>;
1406
- appendExecutionAttestation(record: ExecutionAttestationRecord): Promise<void>;
1407
- listExecutionAttestations(actionInvocationId: string, tenantId: string, spaceId: string): Promise<ExecutionAttestationRecord[]>;
1408
- appendExternalReconciliation(record: ExternalReconciliationRecord): Promise<void>;
1409
- createAdapterInvocation(record: AdapterInvocationRecord): Promise<void>;
1410
- getAdapterInvocation(id: string, scope?: AdapterInvocationScope): Promise<AdapterInvocationRecord | undefined>;
1411
- updateAdapterInvocation(id: string, patch: Partial<Pick<AdapterInvocationRecord, "status" | "output" | "error" | "attempt" | "updatedAt">>, scope?: AdapterInvocationScope): Promise<void>;
1412
- appendEvent(event: AssetEventEnvelope): Promise<void>;
1413
- appendEventWithOutbox(event: AssetEventEnvelope, metadata: OutboxEventMetadata): Promise<void>;
1414
- claimOutbox(input: ClaimOutboxInput): Promise<OutboxRecord[]>;
1415
- markOutboxPublished(id: string, workerId: string, publishedAt: Date, leaseToken?: number): Promise<void>;
1416
- markOutboxFailed(input: {
1417
- id: string;
1418
- workerId: string;
1419
- leaseToken?: number;
1420
- error: string;
1421
- availableAt: Date;
1422
- deadLetter: boolean;
1423
- }): Promise<void>;
1424
- renewOutboxLease(input: {
1425
- id: string;
1426
- workerId: string;
1427
- leaseToken: number;
1428
- leaseDurationMs: number;
1429
- now?: Date;
1430
- }): Promise<boolean>;
1431
- listOutbox(input?: {
1432
- tenantId?: string;
1433
- spaceId?: string;
1434
- statuses?: OutboxStatus[];
1435
- }): Promise<OutboxRecord[]>;
1436
- getOutboxRecord(id: string, tenantId: string, spaceId: string): Promise<OutboxRecord | undefined>;
1437
- requeueOutboxDeadLetter(input: RequeueOutboxDeadLetterStoreInput): Promise<RequeueOutboxDeadLetterStoreResult>;
1438
- listOutboxRequeues(input: {
1439
- tenantId: string;
1440
- spaceId: string;
1441
- outboxId?: string;
1442
- }): Promise<OutboxRequeueRecord[]>;
1443
- nextEventSequence(tenantId: string, spaceId: string): Promise<number>;
1444
- getEntityStateSource(tenantId: string, spaceId: string, entityType: string, entityId: string): Promise<{
1445
- state: string;
1446
- actionInvocationId: string;
1447
- } | undefined>;
1448
- getEntityState(tenantId: string, spaceId: string, entityType: string, entityId: string): Promise<string | undefined>;
1449
- listActionInvocations(input?: ListActionInvocationsInput): Promise<ActionInvocationRecord[]>;
1450
- getHealthCounts(input: PlatformHostHealthQuery): Promise<PlatformHostHealthCounts>;
1451
- claimActionInvocations(input: ClaimActionInvocationsInput): Promise<ActionInvocationRecord[]>;
1452
- updateLeasedActionInvocation(input: UpdateLeasedActionInvocationInput): Promise<boolean>;
1453
- renewActionInvocationLease(input: RenewActionInvocationLeaseInput): Promise<boolean>;
1454
- listEvents(tenantId: string, spaceId: string): Promise<AssetEventEnvelope[]>;
1455
- getEvent(id: string, tenantId: string, spaceId: string): Promise<AssetEventEnvelope | undefined>;
1456
- }
1457
-
1458
- interface PostgresMigration {
1459
- version: number;
1460
- name: string;
1461
- sql: string;
1512
+ export declare class PostgresPlatformHostStore<TDb> implements RecoverablePlatformHostStore<TDb>, ApprovalPlatformHostStore<TDb>, GovernancePlatformHostStore<TDb>, OutboxPlatformHostStore<TDb>, OutboxRequeuePlatformHostStore<TDb> {
1513
+ readonly db: TDb;
1514
+ private readonly sql;
1515
+ readonly transactionWithEvents?: AtomicMutationPlatformHostStore<TDb>["transactionWithEvents"];
1516
+ readonly transactionalOutbox: boolean;
1517
+ constructor(db: TDb, sql: PlatformHostSqlClient, transactionProvider?: PostgresPlatformHostTransactionProvider<TDb>);
1518
+ ensureSchema(): Promise<void>;
1519
+ transaction<TResult>(run: (db: TDb) => Promise<TResult>): Promise<TResult>;
1520
+ createActionInvocation(input: CreateActionInvocationInput): Promise<ActionInvocationRecord>;
1521
+ getActionInvocation(id: string, tenantId: string, spaceId: string): Promise<ActionInvocationRecord | undefined>;
1522
+ updateActionInvocation(id: string, tenantId: string, spaceId: string, patch: ActionInvocationPatch): Promise<void>;
1523
+ recordHitlDecision(actionInvocationId: string, tenantId: string, spaceId: string, decision: HitlDecisionEvidence): Promise<ActionInvocationRecord>;
1524
+ beginApprovalDecision(input: BeginApprovalDecisionInput): Promise<ApprovalDecisionTransitionResult>;
1525
+ appendPolicyEvaluation(record: PolicyEvaluationRecord): Promise<void>;
1526
+ recordMutationGovernance(actionInvocationId: string, tenantId: string, spaceId: string, context: {
1527
+ footprint: NonNullable<ActionInvocationRecord["mutationFootprint"]>;
1528
+ executionPrincipal: NonNullable<ActionInvocationRecord["executionPrincipal"]>;
1529
+ }): Promise<ActionInvocationRecord>;
1530
+ appendPolicyObligations(records: PolicyObligationRecord[]): Promise<void>;
1531
+ listPolicyObligations(actionInvocationId: string, tenantId: string, spaceId: string): Promise<PolicyObligationRecord[]>;
1532
+ updatePolicyObligation(actionInvocationId: string, obligationId: string, status: PolicyObligationRecord["status"], evidenceReferences?: PolicyObligationRecord["evidenceReferences"]): Promise<void>;
1533
+ appendExecutionAttestation(record: ExecutionAttestationRecord): Promise<void>;
1534
+ listExecutionAttestations(actionInvocationId: string, tenantId: string, spaceId: string): Promise<ExecutionAttestationRecord[]>;
1535
+ appendExternalReconciliation(record: ExternalReconciliationRecord): Promise<void>;
1536
+ updateSettledActionInvocation(input: UpdateSettledActionInvocationInput): Promise<boolean>;
1537
+ writeAdapterInvocation(input: AdapterInvocationWriteInput): Promise<boolean>;
1538
+ createAdapterInvocation(record: AdapterInvocationRecord): Promise<void>;
1539
+ getAdapterInvocation(id: string, scope?: AdapterInvocationScope): Promise<AdapterInvocationRecord | undefined>;
1540
+ updateAdapterInvocation(id: string, patch: Partial<Pick<AdapterInvocationRecord, "status" | "output" | "error" | "attempt" | "updatedAt" | "reconciliation">>, scope?: AdapterInvocationScope): Promise<void>;
1541
+ appendEvent(event: AssetEventEnvelope): Promise<void>;
1542
+ appendEventWithOutbox(event: AssetEventEnvelope, metadata: OutboxEventMetadata): Promise<void>;
1543
+ claimOutbox(input: ClaimOutboxInput): Promise<OutboxRecord[]>;
1544
+ markOutboxPublished(id: string, workerId: string, publishedAt: Date, leaseToken?: number): Promise<void>;
1545
+ markOutboxFailed(input: {
1546
+ id: string;
1547
+ workerId: string;
1548
+ leaseToken?: number;
1549
+ error: string;
1550
+ availableAt: Date;
1551
+ deadLetter: boolean;
1552
+ }): Promise<void>;
1553
+ renewOutboxLease(input: {
1554
+ id: string;
1555
+ workerId: string;
1556
+ leaseToken: number;
1557
+ leaseDurationMs: number;
1558
+ now?: Date;
1559
+ }): Promise<boolean>;
1560
+ listOutbox(input?: {
1561
+ tenantId?: string;
1562
+ spaceId?: string;
1563
+ statuses?: OutboxStatus[];
1564
+ }): Promise<OutboxRecord[]>;
1565
+ getOutboxRecord(id: string, tenantId: string, spaceId: string): Promise<OutboxRecord | undefined>;
1566
+ requeueOutboxDeadLetter(input: RequeueOutboxDeadLetterStoreInput): Promise<RequeueOutboxDeadLetterStoreResult>;
1567
+ listOutboxRequeues(input: {
1568
+ tenantId: string;
1569
+ spaceId: string;
1570
+ outboxId?: string;
1571
+ }): Promise<OutboxRequeueRecord[]>;
1572
+ nextEventSequence(tenantId: string, spaceId: string): Promise<number>;
1573
+ getEntityStateSource(tenantId: string, spaceId: string, entityType: string, entityId: string): Promise<{
1574
+ state: string;
1575
+ actionInvocationId: string;
1576
+ } | undefined>;
1577
+ getEntityState(tenantId: string, spaceId: string, entityType: string, entityId: string): Promise<string | undefined>;
1578
+ listActionInvocations(input?: ListActionInvocationsInput): Promise<ActionInvocationRecord[]>;
1579
+ getHealthCounts(input: PlatformHostHealthQuery): Promise<PlatformHostHealthCounts>;
1580
+ claimActionInvocations(input: ClaimActionInvocationsInput): Promise<ActionInvocationRecord[]>;
1581
+ updateLeasedActionInvocation(input: UpdateLeasedActionInvocationInput): Promise<boolean>;
1582
+ renewActionInvocationLease(input: RenewActionInvocationLeaseInput): Promise<boolean>;
1583
+ listEvents(tenantId: string, spaceId: string): Promise<AssetEventEnvelope[]>;
1584
+ getEvent(id: string, tenantId: string, spaceId: string): Promise<AssetEventEnvelope | undefined>;
1585
+ }
1586
+ //#endregion
1587
+ //#region src/postgres-migrations.d.ts
1588
+ export interface PostgresMigration {
1589
+ version: number;
1590
+ name: string;
1591
+ sql: string;
1462
1592
  }
1463
1593
  /**
1464
1594
  * Applies an immutable, ordered migration set in one PostgreSQL transaction.
@@ -1466,74 +1596,76 @@ interface PostgresMigration {
1466
1596
  * The transaction-scoped advisory lock serializes migrators. A previously
1467
1597
  * applied version may be presented again only when its checksum is unchanged.
1468
1598
  */
1469
- declare function applyPostgresMigrations(client: PlatformHostSqlClient, migrations: readonly PostgresMigration[]): Promise<void>;
1470
-
1471
- declare const PARAMETER_DIGEST_ALGORITHM: "fabric-canonical-json-sha256-v1";
1472
-
1473
- declare function digestParameters(parameters: unknown): string;
1474
-
1599
+ export declare function applyPostgresMigrations(client: PlatformHostSqlClient, migrations: readonly PostgresMigration[]): Promise<void>;
1600
+ //#endregion
1601
+ //#region src/command-identity.d.ts
1602
+ export declare const PARAMETER_DIGEST_ALGORITHM: "fabric-canonical-json-sha256-v1";
1603
+ export declare function digestParameters(parameters: unknown): string;
1604
+ //#endregion
1605
+ //#region src/worker.d.ts
1475
1606
  /**
1476
1607
  * Durable store-backed dispatch: the pending invocation row is the queue item.
1477
1608
  * Repeated dispatches are safe because the workflow id is stable per invocation.
1478
1609
  */
1479
- declare function createStoreBackedActionDispatcher(): PlatformActionDispatcher;
1610
+ export declare function createStoreBackedActionDispatcher(): PlatformActionDispatcher;
1480
1611
  /** Claim and execute one bounded batch. Safe to run concurrently across workers. */
1481
- declare function runPlatformActionWorkerCycle<TDb>(options: PlatformActionWorkerOptions<TDb>): Promise<PlatformActionWorkerCycleResult>;
1612
+ export declare function runPlatformActionWorkerCycle<TDb>(options: PlatformActionWorkerOptions<TDb>): Promise<PlatformActionWorkerCycleResult>;
1482
1613
  /** Poll until aborted. Each iteration is bounded and waits without busy-spinning. */
1483
- declare function runPlatformActionWorker<TDb>(options: PlatformActionWorkerOptions<TDb>): Promise<void>;
1484
-
1614
+ export declare function runPlatformActionWorker<TDb>(options: PlatformActionWorkerOptions<TDb>): Promise<void>;
1615
+ //#endregion
1616
+ //#region src/saga-parent-lifecycle.d.ts
1485
1617
  interface HostSagaParentLifecycleIdentity {
1486
- /** Stable identity shared by every retry of the same lifecycle transition. */
1487
- lifecycleId?: string;
1618
+ /** Stable identity shared by every retry of the same lifecycle transition. */
1619
+ lifecycleId?: string;
1488
1620
  }
1489
1621
  /**
1490
1622
  * Durable record of a single step completing within a saga parent.
1491
1623
  * Structurally compatible with {@link import("@fabricorg/platform-temporal").SagaParentProgressRecord}.
1492
1624
  */
1493
- interface HostSagaParentProgressRecord {
1494
- stepId: string;
1495
- index: number;
1496
- total: number;
1497
- completedAt: string;
1498
- }
1499
- interface HostSagaParentProgressInput extends HostSagaParentLifecycleIdentity {
1500
- parentInvocationId: string;
1501
- tenantId: string;
1502
- spaceId: string;
1503
- progress: HostSagaParentProgressRecord;
1504
- }
1505
- interface HostSagaParentApprovalInput extends HostSagaParentLifecycleIdentity {
1506
- parentInvocationId: string;
1507
- tenantId: string;
1508
- spaceId: string;
1509
- stepId: string;
1510
- approvalId: string;
1511
- reason: string;
1512
- }
1513
- interface HostSagaParentCancellationInput extends HostSagaParentLifecycleIdentity {
1514
- parentInvocationId: string;
1515
- tenantId: string;
1516
- spaceId: string;
1517
- reason: string;
1518
- actorId: string;
1519
- }
1520
- interface HostSagaParentCompletionInput extends HostSagaParentLifecycleIdentity {
1521
- parentInvocationId: string;
1522
- tenantId: string;
1523
- spaceId: string;
1524
- result: Record<string, unknown>;
1525
- }
1526
- interface HostSagaParentFailureInput extends HostSagaParentLifecycleIdentity {
1527
- parentInvocationId: string;
1528
- tenantId: string;
1529
- spaceId: string;
1530
- error: string;
1531
- compensation: HostCompensationRecord[];
1532
- }
1533
- interface HostCompensationRecord {
1534
- stepId: string;
1535
- actionId: string;
1536
- error?: string;
1625
+ export interface HostSagaParentProgressRecord {
1626
+ stepId: string;
1627
+ index: number;
1628
+ total: number;
1629
+ completedAt: string;
1630
+ }
1631
+ export interface HostSagaParentProgressInput extends HostSagaParentLifecycleIdentity {
1632
+ parentInvocationId: string;
1633
+ tenantId: string;
1634
+ spaceId: string;
1635
+ progress: HostSagaParentProgressRecord;
1636
+ }
1637
+ export interface HostSagaParentApprovalInput extends HostSagaParentLifecycleIdentity {
1638
+ parentInvocationId: string;
1639
+ tenantId: string;
1640
+ spaceId: string;
1641
+ stepId: string;
1642
+ approvalId: string;
1643
+ reason: string;
1644
+ }
1645
+ export interface HostSagaParentCancellationInput extends HostSagaParentLifecycleIdentity {
1646
+ parentInvocationId: string;
1647
+ tenantId: string;
1648
+ spaceId: string;
1649
+ reason: string;
1650
+ actorId: string;
1651
+ }
1652
+ export interface HostSagaParentCompletionInput extends HostSagaParentLifecycleIdentity {
1653
+ parentInvocationId: string;
1654
+ tenantId: string;
1655
+ spaceId: string;
1656
+ result: Record<string, unknown>;
1657
+ }
1658
+ export interface HostSagaParentFailureInput extends HostSagaParentLifecycleIdentity {
1659
+ parentInvocationId: string;
1660
+ tenantId: string;
1661
+ spaceId: string;
1662
+ error: string;
1663
+ compensation: HostCompensationRecord[];
1664
+ }
1665
+ export interface HostCompensationRecord {
1666
+ stepId: string;
1667
+ actionId: string;
1668
+ error?: string;
1537
1669
  }
1538
1670
  /**
1539
1671
  * Durable saga parent lifecycle contract backed by a Platform Host store.
@@ -1548,17 +1680,17 @@ interface HostCompensationRecord {
1548
1680
  * the persisted progress, approval park, cancellation, completion, or failure
1549
1681
  * without in-memory state.
1550
1682
  */
1551
- interface HostSagaParentLifecycle {
1552
- recordProgress(input: HostSagaParentProgressInput): Promise<void>;
1553
- parkApproval(input: HostSagaParentApprovalInput): Promise<void>;
1554
- cancel(input: HostSagaParentCancellationInput): Promise<void>;
1555
- complete(input: HostSagaParentCompletionInput): Promise<void>;
1556
- fail(input: HostSagaParentFailureInput): Promise<void>;
1557
- }
1558
- interface CreateDurableSagaParentLifecycleOptions<TDb> {
1559
- store: PlatformHostStore<TDb>;
1560
- /** Optional clock for deterministic tests. */
1561
- now?: () => Date;
1683
+ export interface HostSagaParentLifecycle {
1684
+ recordProgress(input: HostSagaParentProgressInput): Promise<void>;
1685
+ parkApproval(input: HostSagaParentApprovalInput): Promise<void>;
1686
+ cancel(input: HostSagaParentCancellationInput): Promise<void>;
1687
+ complete(input: HostSagaParentCompletionInput): Promise<void>;
1688
+ fail(input: HostSagaParentFailureInput): Promise<void>;
1689
+ }
1690
+ export interface CreateDurableSagaParentLifecycleOptions<TDb> {
1691
+ store: PlatformHostStore<TDb>;
1692
+ /** Optional clock for deterministic tests. */
1693
+ now?: () => Date;
1562
1694
  }
1563
1695
  /**
1564
1696
  * Create a {@link HostSagaParentLifecycle} backed by a Platform Host store.
@@ -1568,55 +1700,56 @@ interface CreateDurableSagaParentLifecycleOptions<TDb> {
1568
1700
  * lifecycle event and transitions the parent invocation to the appropriate
1569
1701
  * status so a fresh worker can observe the persisted state after a rollover.
1570
1702
  */
1571
- declare function createDurableSagaParentLifecycle<TDb>(options: CreateDurableSagaParentLifecycleOptions<TDb>): HostSagaParentLifecycle;
1572
-
1573
- interface TenantIsolationScope {
1574
- tenantId: string;
1575
- spaceId: string;
1576
- actorId: string;
1577
- actorType: ActorType;
1578
- }
1579
- interface TenantIsolationSubject<TDb = unknown> {
1580
- host: GovernedActionHost;
1581
- store: RecoverablePlatformHostStore<TDb>;
1582
- /** A governed action registered on the host, and parameters it accepts. */
1583
- actionId: ActionId;
1584
- parameters?: Record<string, unknown>;
1585
- /** Two scopes in different tenants. */
1586
- ours: TenantIsolationScope;
1587
- theirs: TenantIsolationScope;
1588
- /**
1589
- * Optional: a governed read the subject exposes, scoped as the projection
1590
- * host scopes it. Returns what a viewer in `scope` sees for the view. Every
1591
- * row must carry the `tenantId` it belongs to, so the check can tell a row
1592
- * of ours from a row of theirs that merely looks the same; two tenants may
1593
- * legitimately hold equal-looking rows.
1594
- */
1595
- read?(scope: TenantIsolationScope): Promise<{
1596
- allowed: boolean;
1597
- rows: readonly {
1598
- tenantId: string;
1599
- }[];
1600
- }>;
1601
- /**
1602
- * Optional: put the host and store back to a known state before a check.
1603
- * The checks tolerate accumulated state, and each retires any row it
1604
- * creates directly, so this exists for subjects whose store is shared.
1605
- */
1606
- reset?(): Promise<void> | void;
1607
- }
1608
- interface TenantIsolationCheck {
1609
- id: "fabric.tenancy.invocation-scoped-read.v1" | "fabric.tenancy.idempotency-key-scoped.v1" | "fabric.tenancy.events-scoped.v1" | "fabric.tenancy.worker-claim-scoped.v1" | "fabric.tenancy.completion-scoped.v1" | "fabric.tenancy.projection-scoped.v1" | "fabric.tenancy.adapter-invocation-read-scoped.v1" | "fabric.tenancy.adapter-invocation-write-scoped.v1";
1610
- run(subject: TenantIsolationSubject): Promise<string[]>;
1611
- }
1612
- interface TenantIsolationResult {
1613
- passed: boolean;
1614
- checks: Array<{
1615
- id: TenantIsolationCheck["id"];
1616
- status: "passed" | "failed" | "skipped";
1617
- evidence: string[];
1618
- error?: string;
1619
- }>;
1703
+ export declare function createDurableSagaParentLifecycle<TDb>(options: CreateDurableSagaParentLifecycleOptions<TDb>): HostSagaParentLifecycle;
1704
+ //#endregion
1705
+ //#region src/tenant-isolation.d.ts
1706
+ export interface TenantIsolationScope {
1707
+ tenantId: string;
1708
+ spaceId: string;
1709
+ actorId: string;
1710
+ actorType: ActorType;
1711
+ }
1712
+ export interface TenantIsolationSubject<TDb = unknown> {
1713
+ host: GovernedActionHost;
1714
+ store: RecoverablePlatformHostStore<TDb>;
1715
+ /** A governed action registered on the host, and parameters it accepts. */
1716
+ actionId: ActionId;
1717
+ parameters?: Record<string, unknown>;
1718
+ /** Two scopes in different tenants. */
1719
+ ours: TenantIsolationScope;
1720
+ theirs: TenantIsolationScope;
1721
+ /**
1722
+ * Optional: a governed read the subject exposes, scoped as the projection
1723
+ * host scopes it. Returns what a viewer in `scope` sees for the view. Every
1724
+ * row must carry the `tenantId` it belongs to, so the check can tell a row
1725
+ * of ours from a row of theirs that merely looks the same; two tenants may
1726
+ * legitimately hold equal-looking rows.
1727
+ */
1728
+ read?(scope: TenantIsolationScope): Promise<{
1729
+ allowed: boolean;
1730
+ rows: readonly {
1731
+ tenantId: string;
1732
+ }[];
1733
+ }>;
1734
+ /**
1735
+ * Optional: put the host and store back to a known state before a check.
1736
+ * The checks tolerate accumulated state, and each retires any row it
1737
+ * creates directly, so this exists for subjects whose store is shared.
1738
+ */
1739
+ reset?(): Promise<void> | void;
1740
+ }
1741
+ export interface TenantIsolationCheck {
1742
+ id: "fabric.tenancy.invocation-scoped-read.v1" | "fabric.tenancy.idempotency-key-scoped.v1" | "fabric.tenancy.events-scoped.v1" | "fabric.tenancy.worker-claim-scoped.v1" | "fabric.tenancy.completion-scoped.v1" | "fabric.tenancy.projection-scoped.v1" | "fabric.tenancy.adapter-invocation-read-scoped.v1" | "fabric.tenancy.adapter-invocation-write-scoped.v1";
1743
+ run(subject: TenantIsolationSubject): Promise<string[]>;
1744
+ }
1745
+ export interface TenantIsolationResult {
1746
+ passed: boolean;
1747
+ checks: Array<{
1748
+ id: TenantIsolationCheck["id"];
1749
+ status: "passed" | "failed" | "skipped";
1750
+ evidence: string[];
1751
+ error?: string;
1752
+ }>;
1620
1753
  }
1621
1754
  /**
1622
1755
  * The suite any deployment of the host must pass before it claims isolation.
@@ -1629,8 +1762,8 @@ interface TenantIsolationResult {
1629
1762
  * space, or owning invocation; and, when the subject lends a read, a viewer in
1630
1763
  * the other tenant sees nothing of ours.
1631
1764
  */
1632
- declare function tenantIsolationChecks(): readonly TenantIsolationCheck[];
1765
+ export declare function tenantIsolationChecks(): readonly TenantIsolationCheck[];
1633
1766
  /** Run every check, returning each result rather than throwing on the first. */
1634
- declare function runTenantIsolationChecks(subject: TenantIsolationSubject): Promise<TenantIsolationResult>;
1635
-
1636
- export { ActionAdmissionError, type ActionAdmissionRefusal, type ActionApprovalDecision, type ActionAuthorizationInput, type ActionExecutionAuthorizationInput, type ActionExecutionReason, type ActionInvocationPatch, type ActionInvocationRecord, type AdapterInvocationRecord, type AdapterInvocationScope, 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 EnterpriseEventActorDisclosure, type EnterpriseEventEnvelope, type EnterpriseEventPublishContext, type EnterpriseEventPublisher, type ErrorTextRedactionContext, type EventPayloadClassification, type ExecuteActionResult, type ExecuteInvocationOptions, type ExecutionAttestationRecord, type ExternalCompletion, ExternalCompletionError, type ExternalCompletionRefusal, 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 OutboxActorDisclosure, type OutboxEventMetadata, type OutboxPlatformHostStore, type OutboxRecord, type OutboxRelayOptions, type OutboxRelayResult, type OutboxRequeueAuthorizationInput, type OutboxRequeueHost, type OutboxRequeuePlatformHostStore, type OutboxRequeueRecord, type OutboxRequeueRefusal, type OutboxStatus, PARAMETER_DIGEST_ALGORITHM, PLATFORM_HOST_CONTRACT_VERSION, PLATFORM_HOST_HEALTH_CONTRACT_VERSION, PLATFORM_HOST_METRIC_NAMES, type PendingAssetEvent, type PendingExternalCompletion, 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 ReconcileOverdueCompletionsInput, type RecordedExternalCompletion, type RecoverablePlatformHostStore, type RenewActionInvocationLeaseInput, type RequeueOutboxDeadLetterInput, type RequeueOutboxDeadLetterRefusal, type RequeueOutboxDeadLetterResult, type RequeueOutboxDeadLetterStoreInput, type RequeueOutboxDeadLetterStoreResult, type ResolvePoliciesInput, type SubmitActionInput, type SubmitActionResult, type TenantIsolationCheck, type TenantIsolationResult, type TenantIsolationScope, type TenantIsolationSubject, type UpdateLeasedActionInvocationInput, applyPostgresMigrations, cloneOutboxRecord, createDurableSagaParentLifecycle, createGovernedActionHost, createStoreBackedActionDispatcher, digestParameters, emitPlatformHostTelemetry, getPlatformHostHealthSnapshot, outboxActorDisclosure, runOutboxRelayCycle, runPlatformActionWorker, runPlatformActionWorkerCycle, runTenantIsolationChecks, tenantIsolationChecks, toEnterpriseEventEnvelope };
1767
+ export declare function runTenantIsolationChecks(subject: TenantIsolationSubject): Promise<TenantIsolationResult>;
1768
+ //#endregion
1769
+ export { canonicalJson };