@fabricorg/platform-host 8.6.0 → 8.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/README.md +51 -12
- package/dist/index.cjs +96 -44
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +11 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.js +97 -46
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/dist/index.d.cts
CHANGED
|
@@ -275,6 +275,8 @@ export interface FinalizationCheckpoint {
|
|
|
275
275
|
export interface StagedInvocationOrigin {
|
|
276
276
|
parentInvocationId: string;
|
|
277
277
|
stageKey: string;
|
|
278
|
+
/** Host-registered principal name captured in the durable staged intent. */
|
|
279
|
+
principal?: string;
|
|
278
280
|
}
|
|
279
281
|
export interface AgentProposal {
|
|
280
282
|
confidence?: number;
|
|
@@ -757,6 +759,8 @@ export interface StagedInvocationRecord {
|
|
|
757
759
|
parentActionId: ActionId;
|
|
758
760
|
key: string;
|
|
759
761
|
actionId: ActionId;
|
|
762
|
+
/** Host-registered principal name selected by the parent action declaration. */
|
|
763
|
+
principal?: string;
|
|
760
764
|
expectedActionVersion: number;
|
|
761
765
|
parameters: Record<string, unknown>;
|
|
762
766
|
parameterDigest: string;
|
|
@@ -1498,6 +1502,11 @@ export interface PlatformHostOptions<TDb> {
|
|
|
1498
1502
|
registry?: Pick<ModuleRegistry<TDb>, "resolveAction" | "resolvePolicy" | "resolveStateMachine"> & Partial<Pick<ModuleRegistry<TDb>, "orderedModules">>;
|
|
1499
1503
|
/** Resolve vertical- or runtime-local actions without mutating the process-wide registry. */
|
|
1500
1504
|
resolveAction?: (actionId: ActionId) => ActionDefinition<TDb> | undefined;
|
|
1505
|
+
/** Host-owned identities available to parent action declarations for staged dispatch. */
|
|
1506
|
+
stagedInvocationPrincipals?: Readonly<Record<string, {
|
|
1507
|
+
actorId: string;
|
|
1508
|
+
actorType: ActorType;
|
|
1509
|
+
}>>;
|
|
1501
1510
|
adapters?: readonly AdapterImplementation[];
|
|
1502
1511
|
/**
|
|
1503
1512
|
* Supplies the circuit breaker for each adapter call. Defaults to a new
|
|
@@ -2233,11 +2242,13 @@ export declare const MAX_STAGED_INVOCATION_KEY_LENGTH = 128;
|
|
|
2233
2242
|
export declare const MAX_STAGED_INVOCATION_BYTES: number;
|
|
2234
2243
|
export declare const MAX_STAGED_INVOCATION_BATCH_BYTES: number;
|
|
2235
2244
|
export declare const STAGED_INVOCATION_KEY_PATTERN: RegExp;
|
|
2245
|
+
export declare const STAGED_INVOCATION_PRINCIPAL_PATTERN: RegExp;
|
|
2236
2246
|
interface PrepareStagedInvocationBatchInput<TDb> {
|
|
2237
2247
|
parent: Pick<ActionInvocationRecord, "id" | "tenantId" | "spaceId" | "actionId">;
|
|
2238
2248
|
parentAction: ActionDefinition<TDb>;
|
|
2239
2249
|
requests: readonly StagedInvocationRequest[];
|
|
2240
2250
|
resolveAction(actionId: ActionId): ActionDefinition<TDb> | undefined;
|
|
2251
|
+
stagedInvocationPrincipals?: Readonly<Record<string, unknown>>;
|
|
2241
2252
|
redactParameters?(actionId: ActionId, parameters: Record<string, unknown>): Record<string, unknown>;
|
|
2242
2253
|
/** Keys whose parameters already passed the redactor into a durable checkpoint. */
|
|
2243
2254
|
redactedKeys?: readonly string[];
|
package/dist/index.d.ts
CHANGED
|
@@ -275,6 +275,8 @@ export interface FinalizationCheckpoint {
|
|
|
275
275
|
export interface StagedInvocationOrigin {
|
|
276
276
|
parentInvocationId: string;
|
|
277
277
|
stageKey: string;
|
|
278
|
+
/** Host-registered principal name captured in the durable staged intent. */
|
|
279
|
+
principal?: string;
|
|
278
280
|
}
|
|
279
281
|
export interface AgentProposal {
|
|
280
282
|
confidence?: number;
|
|
@@ -757,6 +759,8 @@ export interface StagedInvocationRecord {
|
|
|
757
759
|
parentActionId: ActionId;
|
|
758
760
|
key: string;
|
|
759
761
|
actionId: ActionId;
|
|
762
|
+
/** Host-registered principal name selected by the parent action declaration. */
|
|
763
|
+
principal?: string;
|
|
760
764
|
expectedActionVersion: number;
|
|
761
765
|
parameters: Record<string, unknown>;
|
|
762
766
|
parameterDigest: string;
|
|
@@ -1498,6 +1502,11 @@ export interface PlatformHostOptions<TDb> {
|
|
|
1498
1502
|
registry?: Pick<ModuleRegistry<TDb>, "resolveAction" | "resolvePolicy" | "resolveStateMachine"> & Partial<Pick<ModuleRegistry<TDb>, "orderedModules">>;
|
|
1499
1503
|
/** Resolve vertical- or runtime-local actions without mutating the process-wide registry. */
|
|
1500
1504
|
resolveAction?: (actionId: ActionId) => ActionDefinition<TDb> | undefined;
|
|
1505
|
+
/** Host-owned identities available to parent action declarations for staged dispatch. */
|
|
1506
|
+
stagedInvocationPrincipals?: Readonly<Record<string, {
|
|
1507
|
+
actorId: string;
|
|
1508
|
+
actorType: ActorType;
|
|
1509
|
+
}>>;
|
|
1501
1510
|
adapters?: readonly AdapterImplementation[];
|
|
1502
1511
|
/**
|
|
1503
1512
|
* Supplies the circuit breaker for each adapter call. Defaults to a new
|
|
@@ -2233,11 +2242,13 @@ export declare const MAX_STAGED_INVOCATION_KEY_LENGTH = 128;
|
|
|
2233
2242
|
export declare const MAX_STAGED_INVOCATION_BYTES: number;
|
|
2234
2243
|
export declare const MAX_STAGED_INVOCATION_BATCH_BYTES: number;
|
|
2235
2244
|
export declare const STAGED_INVOCATION_KEY_PATTERN: RegExp;
|
|
2245
|
+
export declare const STAGED_INVOCATION_PRINCIPAL_PATTERN: RegExp;
|
|
2236
2246
|
interface PrepareStagedInvocationBatchInput<TDb> {
|
|
2237
2247
|
parent: Pick<ActionInvocationRecord, "id" | "tenantId" | "spaceId" | "actionId">;
|
|
2238
2248
|
parentAction: ActionDefinition<TDb>;
|
|
2239
2249
|
requests: readonly StagedInvocationRequest[];
|
|
2240
2250
|
resolveAction(actionId: ActionId): ActionDefinition<TDb> | undefined;
|
|
2251
|
+
stagedInvocationPrincipals?: Readonly<Record<string, unknown>>;
|
|
2241
2252
|
redactParameters?(actionId: ActionId, parameters: Record<string, unknown>): Record<string, unknown>;
|
|
2242
2253
|
/** Keys whose parameters already passed the redactor into a durable checkpoint. */
|
|
2243
2254
|
redactedKeys?: readonly string[];
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { types } from "util";
|
|
2
|
-
import { AdapterCircuitBreakerRegistry, AdapterRegistry, FABRIC_GOVERNANCE_CONTRACT_VERSION, ReconciliationRequiredError, aggregatePolicyOutcomes, assertActionFinalization, assertAdapterCircuitBreakerConfig, assertAdapterOutcomeConsistency, assertAdapterStepDeadlines, assertGovernanceRuntimeEvidence, assertMutationGovernanceContext, canonicalJson, createFabricId, evaluatePolicyDefinitions, evaluateStateMachineTransition, executeWithAdapterRetry, isAdapterCircuitOpenError, isReconciliationRequiredError, isRetryableExecutionError } from "@fabricorg/platform";
|
|
2
|
+
import { AdapterCircuitBreakerRegistry, AdapterRegistry, FABRIC_GOVERNANCE_CONTRACT_VERSION, ReconciliationRequiredError, aggregatePolicyOutcomes, assertActionFinalization, assertAdapterCircuitBreakerConfig, assertAdapterOutcomeConsistency, assertAdapterStepDeadlines, assertGovernanceRuntimeEvidence, assertMutationGovernanceContext, canonicalJson, createFabricId, evaluatePolicyDefinitions, evaluateStateMachineTransition, executeWithAdapterRetry, isActorType, isAdapterCircuitOpenError, isReconciliationRequiredError, isRetryableExecutionError } from "@fabricorg/platform";
|
|
3
3
|
import { performance } from "perf_hooks";
|
|
4
4
|
import { assertAssemblyRuntimeCompatible } from "@fabricorg/assembly";
|
|
5
5
|
import { createHash } from "crypto";
|
|
@@ -1374,6 +1374,7 @@ const MAX_STAGED_INVOCATION_KEY_LENGTH = 128;
|
|
|
1374
1374
|
const MAX_STAGED_INVOCATION_BYTES = 65536;
|
|
1375
1375
|
const MAX_STAGED_INVOCATION_BATCH_BYTES = 262144;
|
|
1376
1376
|
const STAGED_INVOCATION_KEY_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._:-]*$/;
|
|
1377
|
+
const STAGED_INVOCATION_PRINCIPAL_PATTERN = /^[a-z][a-z0-9._:-]{0,127}$/;
|
|
1377
1378
|
/** Validate and normalize one immutable batch before its parent transaction commits. */
|
|
1378
1379
|
function prepareStagedInvocationBatch(input) {
|
|
1379
1380
|
if (!Array.isArray(input.requests)) throw new Error("stagedInvocations must be an array.");
|
|
@@ -1393,6 +1394,8 @@ function prepareStagedInvocationBatch(input) {
|
|
|
1393
1394
|
if (!(input.parentAction.stagesInvocations ?? []).includes(request.actionId)) throw new Error(`Action "${input.parentAction.actionId}" may not stage "${String(request.actionId)}".`);
|
|
1394
1395
|
const child = input.resolveAction(request.actionId);
|
|
1395
1396
|
if (!child) throw new Error(`Staged action "${String(request.actionId)}" is not registered.`);
|
|
1397
|
+
const principal = input.parentAction.stagedInvocationPrincipals?.[child.actionId];
|
|
1398
|
+
if (principal !== void 0 && !Object.hasOwn(input.stagedInvocationPrincipals ?? {}, principal)) throw new Error(`Staged invocation principal "${principal}" is not registered with this Platform Host.`);
|
|
1396
1399
|
const parameters = finalizationJson(request.parameters);
|
|
1397
1400
|
if (!parameters || typeof parameters !== "object" || Array.isArray(parameters)) throw new Error(`stagedInvocations[${index}] parameters must be a JSON object.`);
|
|
1398
1401
|
if (!child.schema.safeParse(parameters).success) throw new Error(`stagedInvocations[${index}] parameters do not match action "${child.actionId}".`);
|
|
@@ -1407,24 +1410,27 @@ function prepareStagedInvocationBatch(input) {
|
|
|
1407
1410
|
if (byteLength(canonicalJson({
|
|
1408
1411
|
key: request.key,
|
|
1409
1412
|
actionId: child.actionId,
|
|
1410
|
-
parameters: durableParameters
|
|
1413
|
+
parameters: durableParameters,
|
|
1414
|
+
...principal !== void 0 ? { principal } : {}
|
|
1411
1415
|
})) > 65536) throw new Error(`stagedInvocations[${index}] exceeds ${MAX_STAGED_INVOCATION_BYTES} bytes.`);
|
|
1412
1416
|
return {
|
|
1413
1417
|
key: request.key,
|
|
1414
1418
|
actionId: child.actionId,
|
|
1415
1419
|
expectedActionVersion: child.version,
|
|
1416
1420
|
parameters: durableParameters,
|
|
1417
|
-
parameterDigest: digestParameters(durableParameters)
|
|
1421
|
+
parameterDigest: digestParameters(durableParameters),
|
|
1422
|
+
...principal !== void 0 ? { principal } : {}
|
|
1418
1423
|
};
|
|
1419
1424
|
});
|
|
1420
1425
|
for (const [index, request] of normalized.entries()) if (normalized.findIndex((candidate) => candidate.key === request.key) !== index) throw new Error(`stagedInvocations contains duplicate key "${request.key}".`);
|
|
1421
1426
|
normalized.sort((left, right) => compareText(left.key, right.key) || compareText(left.actionId, right.actionId));
|
|
1422
|
-
const batchIdentity = normalized.map(({ key, actionId, expectedActionVersion, parameters, parameterDigest }) => ({
|
|
1427
|
+
const batchIdentity = normalized.map(({ key, actionId, expectedActionVersion, parameters, parameterDigest, principal }) => ({
|
|
1423
1428
|
key,
|
|
1424
1429
|
actionId,
|
|
1425
1430
|
expectedActionVersion,
|
|
1426
1431
|
parameters,
|
|
1427
|
-
parameterDigest
|
|
1432
|
+
parameterDigest,
|
|
1433
|
+
...principal !== void 0 ? { principal } : {}
|
|
1428
1434
|
}));
|
|
1429
1435
|
if (byteLength(canonicalJson(batchIdentity)) > 262144) throw new Error(`stagedInvocations batch exceeds ${MAX_STAGED_INVOCATION_BATCH_BYTES} bytes.`);
|
|
1430
1436
|
const batchDigest = digestParameters({
|
|
@@ -1459,7 +1465,8 @@ function stagedInvocationRequestIdentity(record) {
|
|
|
1459
1465
|
expectedActionVersion: record.expectedActionVersion,
|
|
1460
1466
|
parameters: record.parameters,
|
|
1461
1467
|
parameterDigest: record.parameterDigest,
|
|
1462
|
-
batchDigest: record.batchDigest
|
|
1468
|
+
batchDigest: record.batchDigest,
|
|
1469
|
+
...record.principal !== void 0 ? { principal: record.principal } : {}
|
|
1463
1470
|
});
|
|
1464
1471
|
}
|
|
1465
1472
|
function cloneStagedInvocationRecord(record) {
|
|
@@ -1526,6 +1533,20 @@ const STAGED_ERROR = Object.freeze({
|
|
|
1526
1533
|
lookup: "Staged child lookup failed."
|
|
1527
1534
|
});
|
|
1528
1535
|
function createGovernedActionHost(options) {
|
|
1536
|
+
const configuredStagedPrincipals = options.stagedInvocationPrincipals;
|
|
1537
|
+
if (configuredStagedPrincipals !== void 0 && (!configuredStagedPrincipals || typeof configuredStagedPrincipals !== "object" || Array.isArray(configuredStagedPrincipals))) throw new Error("stagedInvocationPrincipals must be an object.");
|
|
1538
|
+
const stagedInvocationPrincipals = Object.freeze(Object.fromEntries(Object.entries(configuredStagedPrincipals ?? {}).map(([name, candidate]) => {
|
|
1539
|
+
if (!STAGED_INVOCATION_PRINCIPAL_PATTERN.test(name)) throw new Error(`Invalid staged invocation principal name: ${name}`);
|
|
1540
|
+
if (!candidate || typeof candidate !== "object" || Array.isArray(candidate)) throw new Error(`Staged invocation principal "${name}" must be an object.`);
|
|
1541
|
+
const actorId = candidate.actorId;
|
|
1542
|
+
const actorType = candidate.actorType;
|
|
1543
|
+
if (typeof actorId !== "string" || actorId.length === 0) throw new Error(`Staged invocation principal "${name}" actorId must be a non-empty string.`);
|
|
1544
|
+
if (typeof actorType !== "string" || !isActorType(actorType)) throw new Error(`Staged invocation principal "${name}" has invalid actorType.`);
|
|
1545
|
+
return [name, Object.freeze({
|
|
1546
|
+
actorId,
|
|
1547
|
+
actorType
|
|
1548
|
+
})];
|
|
1549
|
+
})));
|
|
1529
1550
|
if (options.approvalDefaultTtlMs !== void 0 && (!Number.isSafeInteger(options.approvalDefaultTtlMs) || options.approvalDefaultTtlMs <= 0)) throw new Error("approvalDefaultTtlMs must be a positive safe integer in milliseconds.");
|
|
1530
1551
|
if (options.approvalLifecycleEvents) {
|
|
1531
1552
|
const approvalStore = asApprovalStore(options.store);
|
|
@@ -1559,6 +1580,9 @@ function createGovernedActionHost(options) {
|
|
|
1559
1580
|
const configuredActionResolver = options.resolveAction ?? options.registry?.resolveAction;
|
|
1560
1581
|
if (!configuredActionResolver) throw new Error("Platform Host requires an explicit module registry or resolveAction function.");
|
|
1561
1582
|
const actionResolver = configuredActionResolver;
|
|
1583
|
+
if (options.registry?.orderedModules) {
|
|
1584
|
+
for (const module of options.registry.orderedModules) for (const action of module.actions ?? []) for (const principal of Object.values(action.stagedInvocationPrincipals ?? {})) if (!Object.hasOwn(stagedInvocationPrincipals, principal)) throw new Error(`Staged invocation principal "${principal}" referenced by action "${action.actionId}" is not registered with this Platform Host.`);
|
|
1585
|
+
}
|
|
1562
1586
|
const stagedStore = asStagedInvocationStore(options.store);
|
|
1563
1587
|
const declaresStaging = options.registry?.orderedModules?.some((module) => (module.actions ?? []).some((action) => (action.stagesInvocations?.length ?? 0) > 0)) ?? false;
|
|
1564
1588
|
if (declaresStaging && (!stagedStore || !asAtomicMutationStore(options.store))) throw new Error("Staged descendant invocations require a store with transactionalStagedInvocations and transactionWithEvents capabilities.");
|
|
@@ -2702,6 +2726,7 @@ function createGovernedActionHost(options) {
|
|
|
2702
2726
|
parentAction: action,
|
|
2703
2727
|
requests: rawStagedInvocations,
|
|
2704
2728
|
resolveAction: actionResolver,
|
|
2729
|
+
stagedInvocationPrincipals,
|
|
2705
2730
|
redactParameters: options.redactActionParameters,
|
|
2706
2731
|
now: now()
|
|
2707
2732
|
});
|
|
@@ -3573,6 +3598,7 @@ function createGovernedActionHost(options) {
|
|
|
3573
3598
|
parentAction: action,
|
|
3574
3599
|
requests: stagedRequests,
|
|
3575
3600
|
resolveAction: actionResolver,
|
|
3601
|
+
stagedInvocationPrincipals,
|
|
3576
3602
|
redactParameters: options.redactActionParameters,
|
|
3577
3603
|
redactedKeys: handlerStagedInvocations.map((request) => request.key),
|
|
3578
3604
|
now: now()
|
|
@@ -4143,6 +4169,8 @@ function createGovernedActionHost(options) {
|
|
|
4143
4169
|
if (!parent || parent.status !== "completed") throw new Error("Staged parent is not completed.");
|
|
4144
4170
|
const child = actionResolver(record.actionId);
|
|
4145
4171
|
if (!child) throw new StagedDispatchRejectionError("Staged action is no longer registered.");
|
|
4172
|
+
const principal = record.principal !== void 0 && Object.hasOwn(stagedInvocationPrincipals, record.principal) ? stagedInvocationPrincipals[record.principal] : void 0;
|
|
4173
|
+
if (record.principal !== void 0 && !principal) throw new StagedDispatchRejectionError("Staged invocation principal is no longer registered.");
|
|
4146
4174
|
if (child.execution?.authorityMoment === "capture") throw new StagedDispatchRejectionError("Staged action now requires capture-time authority.");
|
|
4147
4175
|
if (!child.schema.safeParse(structuredClone(record.parameters)).success) throw new StagedDispatchRejectionError("Staged parameters no longer match the registered action.");
|
|
4148
4176
|
return submitActionInternal({
|
|
@@ -4150,8 +4178,8 @@ function createGovernedActionHost(options) {
|
|
|
4150
4178
|
parameters: structuredClone(record.parameters),
|
|
4151
4179
|
tenantId: parent.tenantId,
|
|
4152
4180
|
spaceId: parent.spaceId,
|
|
4153
|
-
actorId: parent.actorId,
|
|
4154
|
-
actorType: parent.actorType,
|
|
4181
|
+
actorId: principal?.actorId ?? parent.actorId,
|
|
4182
|
+
actorType: principal?.actorType ?? parent.actorType,
|
|
4155
4183
|
correlationId: parent.correlationId,
|
|
4156
4184
|
causationId: parent.id,
|
|
4157
4185
|
provenance: {
|
|
@@ -4165,7 +4193,8 @@ function createGovernedActionHost(options) {
|
|
|
4165
4193
|
id: record.id,
|
|
4166
4194
|
origin: {
|
|
4167
4195
|
parentInvocationId: parent.id,
|
|
4168
|
-
stageKey: record.key
|
|
4196
|
+
stageKey: record.key,
|
|
4197
|
+
...record.principal !== void 0 ? { principal: record.principal } : {}
|
|
4169
4198
|
},
|
|
4170
4199
|
workerId: lease.workerId,
|
|
4171
4200
|
leaseToken: lease.leaseToken,
|
|
@@ -4835,7 +4864,7 @@ var MemoryPlatformHostStore = class {
|
|
|
4835
4864
|
kind: "existing",
|
|
4836
4865
|
invocation: existing
|
|
4837
4866
|
};
|
|
4838
|
-
if (!this.stagedInvocations.find((record) => record.id === input.stageId && record.tenantId === invocation.tenantId && record.spaceId === invocation.spaceId && record.parentInvocationId === invocation.stagedOrigin.parentInvocationId && record.key === invocation.stagedOrigin.stageKey && record.actionId === invocation.actionId && record.status === "pending" && record.leaseOwner === input.workerId && record.leaseToken === input.leaseToken && record.leaseExpiresAt !== void 0 && record.leaseExpiresAt > now)) return { kind: "lease_lost" };
|
|
4867
|
+
if (!this.stagedInvocations.find((record) => record.id === input.stageId && record.tenantId === invocation.tenantId && record.spaceId === invocation.spaceId && record.parentInvocationId === invocation.stagedOrigin.parentInvocationId && record.key === invocation.stagedOrigin.stageKey && record.actionId === invocation.actionId && record.principal === invocation.stagedOrigin.principal && record.status === "pending" && record.leaseOwner === input.workerId && record.leaseToken === input.leaseToken && record.leaseExpiresAt !== void 0 && record.leaseExpiresAt > now)) return { kind: "lease_lost" };
|
|
4839
4868
|
const createdAt = /* @__PURE__ */ new Date();
|
|
4840
4869
|
const record = {
|
|
4841
4870
|
...invocation,
|
|
@@ -5683,6 +5712,16 @@ var PostgresPlatformHostStore = class PostgresPlatformHostStore {
|
|
|
5683
5712
|
version: 13,
|
|
5684
5713
|
name: "agent_proposal",
|
|
5685
5714
|
sql: `ALTER TABLE fabric_platform.action_invocations ADD COLUMN IF NOT EXISTS agent_proposal jsonb;`
|
|
5715
|
+
},
|
|
5716
|
+
{
|
|
5717
|
+
version: 14,
|
|
5718
|
+
name: "staged_invocation_principals",
|
|
5719
|
+
sql: `
|
|
5720
|
+
ALTER TABLE fabric_platform.staged_invocations
|
|
5721
|
+
ADD COLUMN IF NOT EXISTS principal text;
|
|
5722
|
+
ALTER TABLE fabric_platform.action_invocations
|
|
5723
|
+
ADD COLUMN IF NOT EXISTS staged_origin_principal text;
|
|
5724
|
+
`
|
|
5686
5725
|
}
|
|
5687
5726
|
]);
|
|
5688
5727
|
}
|
|
@@ -5747,9 +5786,9 @@ var PostgresPlatformHostStore = class PostgresPlatformHostStore {
|
|
|
5747
5786
|
const current = input.now ?? /* @__PURE__ */ new Date();
|
|
5748
5787
|
const admitted = invocation.admittedAt !== void 0;
|
|
5749
5788
|
const admittedColumn = admitted ? ",admitted_at" : "";
|
|
5750
|
-
const admittedValue = admitted ? ",$
|
|
5789
|
+
const admittedValue = admitted ? ",$31" : "";
|
|
5751
5790
|
const proposalColumn = invocation.agentProposal !== void 0 ? ",agent_proposal" : "";
|
|
5752
|
-
const proposalValue = invocation.agentProposal !== void 0 ? `,$${admitted ?
|
|
5791
|
+
const proposalValue = invocation.agentProposal !== void 0 ? `,$${admitted ? 32 : 31}::jsonb` : "";
|
|
5753
5792
|
const values = [
|
|
5754
5793
|
invocation.id,
|
|
5755
5794
|
invocation.tenantId,
|
|
@@ -5776,6 +5815,7 @@ var PostgresPlatformHostStore = class PostgresPlatformHostStore {
|
|
|
5776
5815
|
invocation.runtimeEvidence ? JSON.stringify(invocation.runtimeEvidence) : null,
|
|
5777
5816
|
invocation.stagedOrigin.parentInvocationId,
|
|
5778
5817
|
invocation.stagedOrigin.stageKey,
|
|
5818
|
+
invocation.stagedOrigin.principal ?? null,
|
|
5779
5819
|
input.stageId,
|
|
5780
5820
|
input.workerId,
|
|
5781
5821
|
input.leaseToken,
|
|
@@ -5788,10 +5828,11 @@ var PostgresPlatformHostStore = class PostgresPlatformHostStore {
|
|
|
5788
5828
|
result = await this.sql.query(`WITH fence AS (
|
|
5789
5829
|
SELECT stage.id
|
|
5790
5830
|
FROM fabric_platform.staged_invocations AS stage
|
|
5791
|
-
WHERE stage.id=$
|
|
5831
|
+
WHERE stage.id=$27 AND stage.tenant_id=$2 AND stage.space_id=$3
|
|
5792
5832
|
AND stage.parent_invocation_id=$24 AND stage.stage_key=$25 AND stage.action_id=$4
|
|
5793
|
-
AND stage.
|
|
5794
|
-
AND stage.
|
|
5833
|
+
AND stage.principal IS NOT DISTINCT FROM $26
|
|
5834
|
+
AND stage.status='pending' AND stage.lease_owner=$28 AND stage.lease_token=$29
|
|
5835
|
+
AND stage.lease_expires_at IS NOT NULL AND stage.lease_expires_at > $30
|
|
5795
5836
|
FOR SHARE
|
|
5796
5837
|
)
|
|
5797
5838
|
INSERT INTO fabric_platform.action_invocations
|
|
@@ -5799,17 +5840,19 @@ var PostgresPlatformHostStore = class PostgresPlatformHostStore {
|
|
|
5799
5840
|
parameters,result,correlation_id,causation_id,idempotency_key,parameter_digest,
|
|
5800
5841
|
parameter_digest_algorithm,idempotency_actor_id,idempotency_authorization_binding_id,
|
|
5801
5842
|
invocation_provenance,authorization_binding,execution_reason,authorization_binding_id,error,
|
|
5802
|
-
runtime_evidence,staged_parent_invocation_id,staged_stage_key${admittedColumn}${proposalColumn},created_at,updated_at)
|
|
5843
|
+
runtime_evidence,staged_parent_invocation_id,staged_stage_key,staged_origin_principal${admittedColumn}${proposalColumn},created_at,updated_at)
|
|
5803
5844
|
SELECT $1,$2,$3,$4,$5,$6,$7,$8,$9::jsonb,$10::jsonb,$11,$12,$13,$14,$15,$16,$17,
|
|
5804
|
-
$18::jsonb,$19::jsonb,$20,$21,$22,$23::jsonb,$24,$25${admittedValue}${proposalValue},$
|
|
5845
|
+
$18::jsonb,$19::jsonb,$20,$21,$22,$23::jsonb,$24,$25,$26${admittedValue}${proposalValue},$30,$30
|
|
5805
5846
|
FROM fence
|
|
5806
5847
|
ON CONFLICT (tenant_id,space_id,staged_parent_invocation_id,staged_stage_key)
|
|
5807
5848
|
WHERE staged_parent_invocation_id IS NOT NULL AND staged_stage_key IS NOT NULL
|
|
5808
5849
|
DO UPDATE SET id=fabric_platform.action_invocations.id
|
|
5809
5850
|
RETURNING *`, values);
|
|
5810
5851
|
} catch (error) {
|
|
5811
|
-
|
|
5812
|
-
if (
|
|
5852
|
+
const databaseError = error;
|
|
5853
|
+
if (invocation.agentProposal !== void 0 && databaseError?.code === "42703" && typeof databaseError.message === "string" && /\bagent_proposal\b/.test(databaseError.message)) throw new Error("Agent proposals require PostgreSQL migration 13 (agent_proposal); run ensureSchema().", { cause: error });
|
|
5854
|
+
if (databaseError?.code === "42703") throw new Error("A staged child needs PostgreSQL migration 14 (staged_invocation_principals); run ensureSchema() before dispatching staged invocations.", { cause: error });
|
|
5855
|
+
if (databaseError?.code === "42P01") throw new Error("A staged child needs PostgreSQL migration 11 (staged_descendant_invocations); run ensureSchema() before dispatching staged invocations.", { cause: error });
|
|
5813
5856
|
throw error;
|
|
5814
5857
|
}
|
|
5815
5858
|
if (result.rows[0]) {
|
|
@@ -5851,33 +5894,39 @@ var PostgresPlatformHostStore = class PostgresPlatformHostStore {
|
|
|
5851
5894
|
}
|
|
5852
5895
|
for (const record of records) {
|
|
5853
5896
|
if (record.tenantId !== first.tenantId || record.spaceId !== first.spaceId || record.parentInvocationId !== first.parentInvocationId || record.batchDigest !== first.batchDigest) throw new Error(`Invalid staged invocation batch for parent ${first.parentInvocationId}.`);
|
|
5854
|
-
|
|
5855
|
-
|
|
5897
|
+
try {
|
|
5898
|
+
await this.sql.query(`INSERT INTO fabric_platform.staged_invocations
|
|
5899
|
+
(id,tenant_id,space_id,parent_invocation_id,parent_action_id,stage_key,action_id,principal,
|
|
5856
5900
|
expected_action_version,parameters,parameter_digest,batch_digest,status,child_invocation_id,
|
|
5857
5901
|
attempt_count,available_at,lease_owner,lease_expires_at,lease_token,last_error,created_at,updated_at)
|
|
5858
|
-
VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9::jsonb,$
|
|
5859
|
-
|
|
5860
|
-
|
|
5861
|
-
|
|
5862
|
-
|
|
5863
|
-
|
|
5864
|
-
|
|
5865
|
-
|
|
5866
|
-
|
|
5867
|
-
|
|
5868
|
-
|
|
5869
|
-
|
|
5870
|
-
|
|
5871
|
-
|
|
5872
|
-
|
|
5873
|
-
|
|
5874
|
-
|
|
5875
|
-
|
|
5876
|
-
|
|
5877
|
-
|
|
5878
|
-
|
|
5879
|
-
|
|
5880
|
-
|
|
5902
|
+
VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10::jsonb,$11,$12,$13,$14,$15,$16,$17,$18,$19,$20,$21,$22)`, [
|
|
5903
|
+
record.id,
|
|
5904
|
+
record.tenantId,
|
|
5905
|
+
record.spaceId,
|
|
5906
|
+
record.parentInvocationId,
|
|
5907
|
+
record.parentActionId,
|
|
5908
|
+
record.key,
|
|
5909
|
+
record.actionId,
|
|
5910
|
+
record.principal ?? null,
|
|
5911
|
+
record.expectedActionVersion,
|
|
5912
|
+
JSON.stringify(record.parameters),
|
|
5913
|
+
record.parameterDigest,
|
|
5914
|
+
record.batchDigest,
|
|
5915
|
+
record.status,
|
|
5916
|
+
record.childInvocationId ?? null,
|
|
5917
|
+
record.attemptCount,
|
|
5918
|
+
record.availableAt,
|
|
5919
|
+
record.leaseOwner ?? null,
|
|
5920
|
+
record.leaseExpiresAt ?? null,
|
|
5921
|
+
record.leaseToken,
|
|
5922
|
+
record.lastError ?? null,
|
|
5923
|
+
record.createdAt,
|
|
5924
|
+
record.updatedAt
|
|
5925
|
+
]);
|
|
5926
|
+
} catch (error) {
|
|
5927
|
+
if (error?.code === "42703") throw new Error("Staging an invocation needs PostgreSQL migration 14 (staged_invocation_principals); run ensureSchema() before staging invocations.", { cause: error });
|
|
5928
|
+
throw error;
|
|
5929
|
+
}
|
|
5881
5930
|
}
|
|
5882
5931
|
}
|
|
5883
5932
|
async getActionInvocation(id, tenantId, spaceId) {
|
|
@@ -6898,7 +6947,8 @@ function toActionRecord(row) {
|
|
|
6898
6947
|
...row.idempotency_authorization_binding_id ? { idempotencyAuthorizationBindingId: String(row.idempotency_authorization_binding_id) } : {},
|
|
6899
6948
|
...row.staged_parent_invocation_id && row.staged_stage_key ? { stagedOrigin: {
|
|
6900
6949
|
parentInvocationId: String(row.staged_parent_invocation_id),
|
|
6901
|
-
stageKey: String(row.staged_stage_key)
|
|
6950
|
+
stageKey: String(row.staged_stage_key),
|
|
6951
|
+
...row.staged_origin_principal ? { principal: String(row.staged_origin_principal) } : {}
|
|
6902
6952
|
} } : {},
|
|
6903
6953
|
...row.invocation_provenance ? { provenance: row.invocation_provenance } : {},
|
|
6904
6954
|
...row.authorization_binding ? { authorizationBinding: row.authorization_binding } : {},
|
|
@@ -6944,6 +6994,7 @@ function toStagedInvocationRecord(row) {
|
|
|
6944
6994
|
parentActionId: String(row.parent_action_id),
|
|
6945
6995
|
key: String(row.stage_key),
|
|
6946
6996
|
actionId: String(row.action_id),
|
|
6997
|
+
...row.principal ? { principal: String(row.principal) } : {},
|
|
6947
6998
|
expectedActionVersion: Number(row.expected_action_version),
|
|
6948
6999
|
parameters: row.parameters,
|
|
6949
7000
|
parameterDigest: String(row.parameter_digest),
|
|
@@ -8425,6 +8476,6 @@ async function runEventAppendChecks(subject) {
|
|
|
8425
8476
|
};
|
|
8426
8477
|
}
|
|
8427
8478
|
//#endregion
|
|
8428
|
-
export { APPROVAL_DECIDED_EVENT, APPROVAL_EXPIRED_EVENT, APPROVAL_REQUESTED_EVENT, ActionAdmissionError, ExternalCompletionError, IdempotencyConflictError, MAX_APPROVAL_EVIDENCE_BYTES, MAX_STAGED_INVOCATIONS, MAX_STAGED_INVOCATION_BATCH_BYTES, MAX_STAGED_INVOCATION_BYTES, MAX_STAGED_INVOCATION_KEY_LENGTH, MemoryPlatformHostStore, PARAMETER_DIGEST_ALGORITHM, PLATFORM_HOST_CONTRACT_VERSION, PLATFORM_HOST_HEALTH_CONTRACT_VERSION, PLATFORM_HOST_METRIC_NAMES, PostgresPlatformHostStore, STAGED_INVOCATION_KEY_PATTERN, SubmissionRefusalError, applyPostgresMigrations, asStagedInvocationStore, canonicalJson, cloneOutboxRecord, cloneStagedInvocationRecord, createDurableSagaParentLifecycle, createGovernedActionHost, createStoreBackedActionDispatcher, digestParameters, emitPlatformHostTelemetry, eventAppendChecks, getPlatformHostHealthSnapshot, outboxActorDisclosure, prepareStagedInvocationBatch, runEventAppendChecks, runOutboxRelayCycle, runPlatformActionWorker, runPlatformActionWorkerCycle, runTenantIsolationChecks, stagedInvocationRequestIdentity, tenantIsolationChecks, toEnterpriseEventEnvelope };
|
|
8479
|
+
export { APPROVAL_DECIDED_EVENT, APPROVAL_EXPIRED_EVENT, APPROVAL_REQUESTED_EVENT, ActionAdmissionError, ExternalCompletionError, IdempotencyConflictError, MAX_APPROVAL_EVIDENCE_BYTES, MAX_STAGED_INVOCATIONS, MAX_STAGED_INVOCATION_BATCH_BYTES, MAX_STAGED_INVOCATION_BYTES, MAX_STAGED_INVOCATION_KEY_LENGTH, MemoryPlatformHostStore, PARAMETER_DIGEST_ALGORITHM, PLATFORM_HOST_CONTRACT_VERSION, PLATFORM_HOST_HEALTH_CONTRACT_VERSION, PLATFORM_HOST_METRIC_NAMES, PostgresPlatformHostStore, STAGED_INVOCATION_KEY_PATTERN, STAGED_INVOCATION_PRINCIPAL_PATTERN, SubmissionRefusalError, applyPostgresMigrations, asStagedInvocationStore, canonicalJson, cloneOutboxRecord, cloneStagedInvocationRecord, createDurableSagaParentLifecycle, createGovernedActionHost, createStoreBackedActionDispatcher, digestParameters, emitPlatformHostTelemetry, eventAppendChecks, getPlatformHostHealthSnapshot, outboxActorDisclosure, prepareStagedInvocationBatch, runEventAppendChecks, runOutboxRelayCycle, runPlatformActionWorker, runPlatformActionWorkerCycle, runTenantIsolationChecks, stagedInvocationRequestIdentity, tenantIsolationChecks, toEnterpriseEventEnvelope };
|
|
8429
8480
|
|
|
8430
8481
|
//# sourceMappingURL=index.js.map
|