@fabricorg/platform 1.2.0 → 1.4.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.
Files changed (50) hide show
  1. package/CHANGELOG.md +37 -0
  2. package/dist/actions/index.cjs +6 -6
  3. package/dist/actions/index.d.cts +14 -0
  4. package/dist/actions/index.d.ts +14 -0
  5. package/dist/actions/index.js +1 -1
  6. package/dist/adapters/index.cjs +9 -9
  7. package/dist/adapters/index.d.cts +17 -1
  8. package/dist/adapters/index.d.ts +17 -1
  9. package/dist/adapters/index.js +1 -1
  10. package/dist/{chunk-LDPBQ72C.cjs → chunk-2AE6TMAX.cjs} +6 -2
  11. package/dist/{chunk-LDPBQ72C.cjs.map → chunk-2AE6TMAX.cjs.map} +1 -1
  12. package/dist/{chunk-4QOA3VU5.js → chunk-2W6FORTE.js} +2 -2
  13. package/dist/{chunk-4QOA3VU5.js.map → chunk-2W6FORTE.js.map} +1 -1
  14. package/dist/{chunk-NHGBTPPE.js → chunk-B5DOGDPG.js} +6 -2
  15. package/dist/{chunk-NHGBTPPE.js.map → chunk-B5DOGDPG.js.map} +1 -1
  16. package/dist/{chunk-AWP6JDD5.js → chunk-DCC3UIUJ.js} +3 -3
  17. package/dist/{chunk-AWP6JDD5.js.map → chunk-DCC3UIUJ.js.map} +1 -1
  18. package/dist/{chunk-DTY3CHQZ.js → chunk-FAG2RTPM.js} +2 -2
  19. package/dist/chunk-FAG2RTPM.js.map +1 -0
  20. package/dist/{chunk-63MYMAEX.js → chunk-GRBZYDEV.js} +6 -4
  21. package/dist/chunk-GRBZYDEV.js.map +1 -0
  22. package/dist/{chunk-3UBX7KQM.cjs → chunk-KIVQBZOA.cjs} +7 -5
  23. package/dist/chunk-KIVQBZOA.cjs.map +1 -0
  24. package/dist/{chunk-LZNXUTJQ.js → chunk-MC3GSVJ6.js} +3 -3
  25. package/dist/{chunk-LZNXUTJQ.js.map → chunk-MC3GSVJ6.js.map} +1 -1
  26. package/dist/{chunk-BFQNKQJE.cjs → chunk-MSABJAED.cjs} +2 -2
  27. package/dist/{chunk-BFQNKQJE.cjs.map → chunk-MSABJAED.cjs.map} +1 -1
  28. package/dist/{chunk-3BGFHSSK.cjs → chunk-USDLP4E7.cjs} +4 -4
  29. package/dist/{chunk-3BGFHSSK.cjs.map → chunk-USDLP4E7.cjs.map} +1 -1
  30. package/dist/{chunk-N2BBUKCX.cjs → chunk-XZQZQ5SW.cjs} +2 -2
  31. package/dist/chunk-XZQZQ5SW.cjs.map +1 -0
  32. package/dist/{chunk-UITRHBZH.cjs → chunk-ZBXFRJON.cjs} +6 -6
  33. package/dist/{chunk-UITRHBZH.cjs.map → chunk-ZBXFRJON.cjs.map} +1 -1
  34. package/dist/events/index.cjs +2 -2
  35. package/dist/events/index.js +1 -1
  36. package/dist/index.cjs +37 -37
  37. package/dist/index.d.cts +1 -1
  38. package/dist/index.d.ts +1 -1
  39. package/dist/index.js +6 -6
  40. package/dist/manifest/index.cjs +9 -9
  41. package/dist/manifest/index.js +3 -3
  42. package/dist/modules/index.cjs +10 -10
  43. package/dist/modules/index.js +2 -2
  44. package/dist/testing/index.cjs +5 -5
  45. package/dist/testing/index.js +2 -2
  46. package/package.json +1 -1
  47. package/dist/chunk-3UBX7KQM.cjs.map +0 -1
  48. package/dist/chunk-63MYMAEX.js.map +0 -1
  49. package/dist/chunk-DTY3CHQZ.js.map +0 -1
  50. package/dist/chunk-N2BBUKCX.cjs.map +0 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,42 @@
1
1
  # @fabricorg/platform
2
2
 
3
+ ## 1.4.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 4c358ad: `ActionExecutionContract` gains an optional `completionDeadlineMs`. The registry refuses it on `completion: "immediate"`, since nothing external completes such an action, and refuses a non-positive value; both are new fields and break no existing manifest. `AdapterExecutionResult` gains `acceptedExternalOperation`, the explicit signal that a successful adapter call handed the work to an external system that will finish it by the given reference. Four host lifecycle event types are added: `ExternalOperationAccepted`, `ExternalOperationCompleted`, `ExternalOperationFailed`, `ExternalOperationContradicted`. All additive.
8
+
9
+ ## 1.3.0
10
+
11
+ ### Minor Changes
12
+
13
+ - 9b2e55b: Close what a fourth review found: each earlier fix closed one instance of a class and left its
14
+ siblings.
15
+
16
+ **Replay disposition is now exhaustive over `ActionStatus`.** The previous fix enumerated the two
17
+ statuses that looked like refusals, so `failed`, `validation_failed` and `waiting_for_approval` fell
18
+ through and were deleted from the queue and reported to the operator as applied — the same bug the
19
+ fix set out to kill, one layer in. Any returned outcome now means the platform holds the invocation,
20
+ so the capture leaves the queue either way; what differs is whether a person needs to hear about it.
21
+ An undeterminable adapter outcome is reported as `unknown` rather than `refused`, because the effect
22
+ may well have happened. `isSettledReplayFailure` learned the refusals the sibling commit introduced,
23
+ including a capture rejected for age, which can never come good.
24
+
25
+ **A replay without `capturedAt` is refused.** It was reachable only through an untyped cast, so
26
+ omitting it skipped the age check entirely and stamped receipt time into durable capture evidence.
27
+
28
+ **A capability can name a namespaced port.** `definePort` required a dot and the manifest validator
29
+ forbade one, so no real capability could name a defined port and the certification gate was
30
+ unreachable. Certification is also checked structurally rather than by the presence of a property, so
31
+ a hand-written claim no longer satisfies the gate that exists to demand evidence, and a port
32
+ requirement narrows its candidates as each constraint is applied.
33
+
34
+ **`assertPortSuiteHasTeeth` names every vacuous check** rather than returning on the first one that
35
+ bites, and a reference port is actually run through it. The payments control asserts its result, so
36
+ an adapter that never charges no longer certifies. The capability-reference grammar matches the
37
+ platform's own view-name rule instead of being stricter than it, and ambiguity is counted by
38
+ occurrence across views and intents rather than by comparing names within one contract.
39
+
3
40
  ## 1.2.0
4
41
 
5
42
  ### Minor Changes
@@ -1,28 +1,28 @@
1
1
  'use strict';
2
2
 
3
- var chunkBFQNKQJE_cjs = require('../chunk-BFQNKQJE.cjs');
3
+ var chunkMSABJAED_cjs = require('../chunk-MSABJAED.cjs');
4
4
 
5
5
 
6
6
 
7
7
  Object.defineProperty(exports, "ACTOR_TYPES", {
8
8
  enumerable: true,
9
- get: function () { return chunkBFQNKQJE_cjs.ACTOR_TYPES; }
9
+ get: function () { return chunkMSABJAED_cjs.ACTOR_TYPES; }
10
10
  });
11
11
  Object.defineProperty(exports, "assertActionId", {
12
12
  enumerable: true,
13
- get: function () { return chunkBFQNKQJE_cjs.assertActionId; }
13
+ get: function () { return chunkMSABJAED_cjs.assertActionId; }
14
14
  });
15
15
  Object.defineProperty(exports, "assertActorType", {
16
16
  enumerable: true,
17
- get: function () { return chunkBFQNKQJE_cjs.assertActorType; }
17
+ get: function () { return chunkMSABJAED_cjs.assertActorType; }
18
18
  });
19
19
  Object.defineProperty(exports, "createActionRegistry", {
20
20
  enumerable: true,
21
- get: function () { return chunkBFQNKQJE_cjs.createActionRegistry; }
21
+ get: function () { return chunkMSABJAED_cjs.createActionRegistry; }
22
22
  });
23
23
  Object.defineProperty(exports, "isActorType", {
24
24
  enumerable: true,
25
- get: function () { return chunkBFQNKQJE_cjs.isActorType; }
25
+ get: function () { return chunkMSABJAED_cjs.isActorType; }
26
26
  });
27
27
  //# sourceMappingURL=index.cjs.map
28
28
  //# sourceMappingURL=index.cjs.map
@@ -99,7 +99,21 @@ interface ActionExecutionContract {
99
99
  connectivity: ActionConnectivity;
100
100
  authorityMoment: AuthorityMoment;
101
101
  idempotency: ActionIdempotencyStance;
102
+ /**
103
+ * `immediate`: the invocation settles within the host's execution.
104
+ * `accepted` and `long-running`: an adapter may hand the work to an
105
+ * external system and the invocation stays running until that system
106
+ * completes it by reference through the host's completion ingress.
107
+ * Declare `completionDeadlineMs` on a `long-running` action so a callback
108
+ * that never comes is noticed rather than waited on forever.
109
+ */
102
110
  completion: ActionCompletionMode;
111
+ /**
112
+ * How long an accepted handoff may wait for its completion before the host
113
+ * moves the invocation to reconciliation. Without it, nothing sweeps the
114
+ * handoff. Refused on `immediate`, since nothing external completes it.
115
+ */
116
+ completionDeadlineMs?: number;
103
117
  consistency: ActionConsistency;
104
118
  sensitivity?: ActionDataSensitivity;
105
119
  }
@@ -99,7 +99,21 @@ interface ActionExecutionContract {
99
99
  connectivity: ActionConnectivity;
100
100
  authorityMoment: AuthorityMoment;
101
101
  idempotency: ActionIdempotencyStance;
102
+ /**
103
+ * `immediate`: the invocation settles within the host's execution.
104
+ * `accepted` and `long-running`: an adapter may hand the work to an
105
+ * external system and the invocation stays running until that system
106
+ * completes it by reference through the host's completion ingress.
107
+ * Declare `completionDeadlineMs` on a `long-running` action so a callback
108
+ * that never comes is noticed rather than waited on forever.
109
+ */
102
110
  completion: ActionCompletionMode;
111
+ /**
112
+ * How long an accepted handoff may wait for its completion before the host
113
+ * moves the invocation to reconciliation. Without it, nothing sweeps the
114
+ * handoff. Refused on `immediate`, since nothing external completes it.
115
+ */
116
+ completionDeadlineMs?: number;
103
117
  consistency: ActionConsistency;
104
118
  sensitivity?: ActionDataSensitivity;
105
119
  }
@@ -1,3 +1,3 @@
1
- export { ACTOR_TYPES, assertActionId, assertActorType, createActionRegistry, isActorType } from '../chunk-4QOA3VU5.js';
1
+ export { ACTOR_TYPES, assertActionId, assertActorType, createActionRegistry, isActorType } from '../chunk-2W6FORTE.js';
2
2
  //# sourceMappingURL=index.js.map
3
3
  //# sourceMappingURL=index.js.map
@@ -1,40 +1,40 @@
1
1
  'use strict';
2
2
 
3
- var chunkN2BBUKCX_cjs = require('../chunk-N2BBUKCX.cjs');
3
+ var chunkXZQZQ5SW_cjs = require('../chunk-XZQZQ5SW.cjs');
4
4
 
5
5
 
6
6
 
7
7
  Object.defineProperty(exports, "AdapterRegistry", {
8
8
  enumerable: true,
9
- get: function () { return chunkN2BBUKCX_cjs.AdapterRegistry; }
9
+ get: function () { return chunkXZQZQ5SW_cjs.AdapterRegistry; }
10
10
  });
11
11
  Object.defineProperty(exports, "MissingAdapterRegistrationError", {
12
12
  enumerable: true,
13
- get: function () { return chunkN2BBUKCX_cjs.MissingAdapterRegistrationError; }
13
+ get: function () { return chunkXZQZQ5SW_cjs.MissingAdapterRegistrationError; }
14
14
  });
15
15
  Object.defineProperty(exports, "assertAdapterOutcomeConsistency", {
16
16
  enumerable: true,
17
- get: function () { return chunkN2BBUKCX_cjs.assertAdapterOutcomeConsistency; }
17
+ get: function () { return chunkXZQZQ5SW_cjs.assertAdapterOutcomeConsistency; }
18
18
  });
19
19
  Object.defineProperty(exports, "classifyAdapterOutcome", {
20
20
  enumerable: true,
21
- get: function () { return chunkN2BBUKCX_cjs.classifyAdapterOutcome; }
21
+ get: function () { return chunkXZQZQ5SW_cjs.classifyAdapterOutcome; }
22
22
  });
23
23
  Object.defineProperty(exports, "executeWithAdapterRetry", {
24
24
  enumerable: true,
25
- get: function () { return chunkN2BBUKCX_cjs.executeWithAdapterRetry; }
25
+ get: function () { return chunkXZQZQ5SW_cjs.executeWithAdapterRetry; }
26
26
  });
27
27
  Object.defineProperty(exports, "getRetryDelayMs", {
28
28
  enumerable: true,
29
- get: function () { return chunkN2BBUKCX_cjs.getRetryDelayMs; }
29
+ get: function () { return chunkXZQZQ5SW_cjs.getRetryDelayMs; }
30
30
  });
31
31
  Object.defineProperty(exports, "resolveAdapterRetryPolicy", {
32
32
  enumerable: true,
33
- get: function () { return chunkN2BBUKCX_cjs.resolveAdapterRetryPolicy; }
33
+ get: function () { return chunkXZQZQ5SW_cjs.resolveAdapterRetryPolicy; }
34
34
  });
35
35
  Object.defineProperty(exports, "shouldRetryAdapterOutcome", {
36
36
  enumerable: true,
37
- get: function () { return chunkN2BBUKCX_cjs.shouldRetryAdapterOutcome; }
37
+ get: function () { return chunkXZQZQ5SW_cjs.shouldRetryAdapterOutcome; }
38
38
  });
39
39
  //# sourceMappingURL=index.cjs.map
40
40
  //# sourceMappingURL=index.cjs.map
@@ -44,6 +44,20 @@ interface AdapterOutcomeEvidence {
44
44
  effectMayHaveApplied?: boolean;
45
45
  observedAt: Date | string;
46
46
  }
47
+ /**
48
+ * An adapter handed the work to an external system that will finish it later.
49
+ *
50
+ * Explicit rather than inferred from evidence: a successful adapter call that
51
+ * merely records a reference is not the same as one that has left the outcome
52
+ * in someone else's hands. The host keeps the invocation running and expects a
53
+ * completion carrying this reference through its completion ingress.
54
+ */
55
+ interface AcceptedExternalOperation {
56
+ /** Opaque, non-secret reference the external system will complete by. */
57
+ externalReference: string;
58
+ /** When the external system said it expects to finish, if it said. */
59
+ expectedBy?: Date | string;
60
+ }
47
61
  interface AdapterExecutionResult {
48
62
  success: boolean;
49
63
  correlationId?: string;
@@ -52,6 +66,8 @@ interface AdapterExecutionResult {
52
66
  outcome?: AdapterOutcomeKind;
53
67
  /** Durable evidence for ambiguous or timeout outcomes requiring reconciliation. */
54
68
  outcomeEvidence?: AdapterOutcomeEvidence;
69
+ /** Present when a successful call handed the work off to finish elsewhere. */
70
+ acceptedExternalOperation?: AcceptedExternalOperation;
55
71
  }
56
72
  type AdapterExecutor = (input: Record<string, unknown>, context: AdapterExecutionContext) => Promise<AdapterExecutionResult>;
57
73
  interface AdapterRetryPolicy {
@@ -155,4 +171,4 @@ declare function shouldRetryAdapterOutcome(kind: AdapterOutcomeKind, idempotent:
155
171
  declare function assertAdapterOutcomeConsistency(result: AdapterExecutionResult): void;
156
172
  declare function executeWithAdapterRetry<T>(options: ExecuteWithRetryOptions<T>): Promise<T>;
157
173
 
158
- export { type AdapterAttempt, type AdapterCircuitBreakerConfig, type AdapterExecutionContext, type AdapterExecutionResult, type AdapterExecutor, type AdapterImplementation, type AdapterOutcomeEvidence, type AdapterOutcomeKind, AdapterRegistry, type AdapterRetryPolicy, type ExecuteWithRetryOptions, MissingAdapterRegistrationError, type ResolvedAdapterRetryPolicy, assertAdapterOutcomeConsistency, classifyAdapterOutcome, executeWithAdapterRetry, getRetryDelayMs, resolveAdapterRetryPolicy, shouldRetryAdapterOutcome };
174
+ export { type AcceptedExternalOperation, type AdapterAttempt, type AdapterCircuitBreakerConfig, type AdapterExecutionContext, type AdapterExecutionResult, type AdapterExecutor, type AdapterImplementation, type AdapterOutcomeEvidence, type AdapterOutcomeKind, AdapterRegistry, type AdapterRetryPolicy, type ExecuteWithRetryOptions, MissingAdapterRegistrationError, type ResolvedAdapterRetryPolicy, assertAdapterOutcomeConsistency, classifyAdapterOutcome, executeWithAdapterRetry, getRetryDelayMs, resolveAdapterRetryPolicy, shouldRetryAdapterOutcome };
@@ -44,6 +44,20 @@ interface AdapterOutcomeEvidence {
44
44
  effectMayHaveApplied?: boolean;
45
45
  observedAt: Date | string;
46
46
  }
47
+ /**
48
+ * An adapter handed the work to an external system that will finish it later.
49
+ *
50
+ * Explicit rather than inferred from evidence: a successful adapter call that
51
+ * merely records a reference is not the same as one that has left the outcome
52
+ * in someone else's hands. The host keeps the invocation running and expects a
53
+ * completion carrying this reference through its completion ingress.
54
+ */
55
+ interface AcceptedExternalOperation {
56
+ /** Opaque, non-secret reference the external system will complete by. */
57
+ externalReference: string;
58
+ /** When the external system said it expects to finish, if it said. */
59
+ expectedBy?: Date | string;
60
+ }
47
61
  interface AdapterExecutionResult {
48
62
  success: boolean;
49
63
  correlationId?: string;
@@ -52,6 +66,8 @@ interface AdapterExecutionResult {
52
66
  outcome?: AdapterOutcomeKind;
53
67
  /** Durable evidence for ambiguous or timeout outcomes requiring reconciliation. */
54
68
  outcomeEvidence?: AdapterOutcomeEvidence;
69
+ /** Present when a successful call handed the work off to finish elsewhere. */
70
+ acceptedExternalOperation?: AcceptedExternalOperation;
55
71
  }
56
72
  type AdapterExecutor = (input: Record<string, unknown>, context: AdapterExecutionContext) => Promise<AdapterExecutionResult>;
57
73
  interface AdapterRetryPolicy {
@@ -155,4 +171,4 @@ declare function shouldRetryAdapterOutcome(kind: AdapterOutcomeKind, idempotent:
155
171
  declare function assertAdapterOutcomeConsistency(result: AdapterExecutionResult): void;
156
172
  declare function executeWithAdapterRetry<T>(options: ExecuteWithRetryOptions<T>): Promise<T>;
157
173
 
158
- export { type AdapterAttempt, type AdapterCircuitBreakerConfig, type AdapterExecutionContext, type AdapterExecutionResult, type AdapterExecutor, type AdapterImplementation, type AdapterOutcomeEvidence, type AdapterOutcomeKind, AdapterRegistry, type AdapterRetryPolicy, type ExecuteWithRetryOptions, MissingAdapterRegistrationError, type ResolvedAdapterRetryPolicy, assertAdapterOutcomeConsistency, classifyAdapterOutcome, executeWithAdapterRetry, getRetryDelayMs, resolveAdapterRetryPolicy, shouldRetryAdapterOutcome };
174
+ export { type AcceptedExternalOperation, type AdapterAttempt, type AdapterCircuitBreakerConfig, type AdapterExecutionContext, type AdapterExecutionResult, type AdapterExecutor, type AdapterImplementation, type AdapterOutcomeEvidence, type AdapterOutcomeKind, AdapterRegistry, type AdapterRetryPolicy, type ExecuteWithRetryOptions, MissingAdapterRegistrationError, type ResolvedAdapterRetryPolicy, assertAdapterOutcomeConsistency, classifyAdapterOutcome, executeWithAdapterRetry, getRetryDelayMs, resolveAdapterRetryPolicy, shouldRetryAdapterOutcome };
@@ -1,3 +1,3 @@
1
- export { AdapterRegistry, MissingAdapterRegistrationError, assertAdapterOutcomeConsistency, classifyAdapterOutcome, executeWithAdapterRetry, getRetryDelayMs, resolveAdapterRetryPolicy, shouldRetryAdapterOutcome } from '../chunk-DTY3CHQZ.js';
1
+ export { AdapterRegistry, MissingAdapterRegistrationError, assertAdapterOutcomeConsistency, classifyAdapterOutcome, executeWithAdapterRetry, getRetryDelayMs, resolveAdapterRetryPolicy, shouldRetryAdapterOutcome } from '../chunk-FAG2RTPM.js';
2
2
  //# sourceMappingURL=index.js.map
3
3
  //# sourceMappingURL=index.js.map
@@ -12,6 +12,10 @@ var BUILT_IN_EVENT_TYPES = Object.freeze([
12
12
  "AdapterInvocationStarted",
13
13
  "AdapterInvocationSucceeded",
14
14
  "AdapterInvocationFailed",
15
+ "ExternalOperationAccepted",
16
+ "ExternalOperationCompleted",
17
+ "ExternalOperationFailed",
18
+ "ExternalOperationContradicted",
15
19
  "WebhookReceived"
16
20
  ]);
17
21
  function createEventContractRegistry(input = {}) {
@@ -36,5 +40,5 @@ function createEventContractRegistry(input = {}) {
36
40
  }
37
41
 
38
42
  exports.createEventContractRegistry = createEventContractRegistry;
39
- //# sourceMappingURL=chunk-LDPBQ72C.cjs.map
40
- //# sourceMappingURL=chunk-LDPBQ72C.cjs.map
43
+ //# sourceMappingURL=chunk-2AE6TMAX.cjs.map
44
+ //# sourceMappingURL=chunk-2AE6TMAX.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../events/index.ts"],"names":[],"mappings":";;;AAgCA,IAAM,sBAAA,GAAyB,OAAO,MAAA,CAAO;AAAA,EAC5C,kBAAA;AAAA,EACA,kBAAA;AAAA,EACA;AACD,CAAC,CAAA;AAED,IAAM,oBAAA,GAAuB,OAAO,MAAA,CAAO;AAAA,EAC1C,mBAAA;AAAA,EACA,mBAAA;AAAA,EACA,0BAAA;AAAA,EACA,4BAAA;AAAA,EACA,yBAAA;AAAA,EACA;AACD,CAAC,CAAA;AAeM,SAAS,2BAAA,CAA4B,KAAA,GAA8E,EAAC,EAA0B;AACpJ,EAAA,MAAM,UAAA,mBAAa,IAAI,GAAA,CAAI,CAAC,GAAG,oBAAA,EAAsB,GAAI,KAAA,CAAM,UAAA,IAAc,EAAG,CAAC,CAAA;AACjF,EAAA,MAAM,YAAA,mBAAe,IAAI,GAAA,CAAI,CAAC,GAAG,sBAAA,EAAwB,GAAI,KAAA,CAAM,YAAA,IAAgB,EAAG,CAAC,CAAA;AACvF,EAAA,OAAO;AAAA,IACN,kBAAkB,SAAA,EAAW;AAC5B,MAAA,IAAI,CAAC,SAAA,EAAW;AACf,QAAA,MAAM,IAAI,MAAM,4BAA4B,CAAA;AAAA,MAC7C;AACA,MAAA,UAAA,CAAW,IAAI,SAAS,CAAA;AAAA,IACzB,CAAA;AAAA,IACA,oBAAoB,WAAA,EAAa;AAChC,MAAA,IAAI,CAAC,WAAA,EAAa,MAAM,IAAI,MAAM,8BAA8B,CAAA;AAChE,MAAA,YAAA,CAAa,IAAI,WAAW,CAAA;AAAA,IAC7B,CAAA;AAAA,IACA,YAAA,EAAc,CAAC,SAAA,KAAc,UAAA,CAAW,IAAI,SAAS,CAAA;AAAA,IACrD,cAAA,EAAgB,CAAC,WAAA,KAAgB,YAAA,CAAa,IAAI,WAAW,CAAA;AAAA,IAC7D,YAAY,MAAM,KAAA,CAAM,IAAA,CAAK,UAAU,EAAE,IAAA,EAAK;AAAA,IAC9C,cAAc,MAAM,KAAA,CAAM,IAAA,CAAK,YAAY,EAAE,IAAA;AAAK,GACnD;AACD","file":"chunk-LDPBQ72C.cjs","sourcesContent":["export interface AssetEventEnvelope<TPayload = unknown> {\n\tid: string;\n\ttenantId: string;\n\tspaceId: string;\n\teventType: string;\n\teventSchemaVersion: number;\n\tsubjectType: string;\n\tsubjectId: string;\n\tactorId: string;\n\tactorType: string;\n\tactionInvocationId?: string;\n\tpayload: TPayload;\n\tsequence: number;\n\toccurredAt: Date;\n\trecordedAt: Date;\n\tcorrelationId: string;\n\tcausationId?: string;\n\tprovenance?: EventProvenance;\n\t/**\n\t * Mirrors the emitting action's declared consistency. Present only when the\n\t * action declares `provisional-until-reconciled`, so a consumer can tell a\n\t * settled fact from one still awaiting reconciliation without a lookup.\n\t * Additive and optional: tolerant consumers that ignore it stay correct.\n\t */\n\tconsistency?: \"authoritative-now\" | \"provisional-until-reconciled\";\n}\n\nexport interface EventProvenance {\n\tsource: \"ui\" | \"api\" | \"agent\" | \"worker\" | \"system\" | (string & {});\n\tauditAttributes?: Record<string, string>;\n}\n\nconst BUILT_IN_SUBJECT_TYPES = Object.freeze([\n\t\"ActionInvocation\",\n\t\"PolicyEvaluation\",\n\t\"AdapterInvocation\",\n]);\n\nconst BUILT_IN_EVENT_TYPES = Object.freeze([\n\t\"ComplianceBlocked\",\n\t\"StateTransitioned\",\n\t\"AdapterInvocationStarted\",\n\t\"AdapterInvocationSucceeded\",\n\t\"AdapterInvocationFailed\",\n\t\"WebhookReceived\",\n]);\n\nexport type AssetEventSubjectType = string;\nexport type AssetEventType = string;\nexport type AssetEventActorType = \"natural_person\" | \"agent\" | \"adapter\" | \"system\" | \"service_account\" | \"external_system\" | \"integration\";\n\nexport interface EventContractRegistry {\n\tregisterEventType(eventType: string): void;\n\tregisterSubjectType(subjectType: string): void;\n\thasEventType(eventType: string): boolean;\n\thasSubjectType(subjectType: string): boolean;\n\teventTypes(): string[];\n\tsubjectTypes(): string[];\n}\n\nexport function createEventContractRegistry(input: { eventTypes?: readonly string[]; subjectTypes?: readonly string[] } = {}): EventContractRegistry {\n\tconst eventTypes = new Set([...BUILT_IN_EVENT_TYPES, ...(input.eventTypes ?? [])]);\n\tconst subjectTypes = new Set([...BUILT_IN_SUBJECT_TYPES, ...(input.subjectTypes ?? [])]);\n\treturn {\n\t\tregisterEventType(eventType) {\n\t\t\tif (!eventType) {\n\t\t\t\tthrow new Error(\"Event type cannot be empty\");\n\t\t\t}\n\t\t\teventTypes.add(eventType);\n\t\t},\n\t\tregisterSubjectType(subjectType) {\n\t\t\tif (!subjectType) throw new Error(\"Subject type cannot be empty\");\n\t\t\tsubjectTypes.add(subjectType);\n\t\t},\n\t\thasEventType: (eventType) => eventTypes.has(eventType),\n\t\thasSubjectType: (subjectType) => subjectTypes.has(subjectType),\n\t\teventTypes: () => Array.from(eventTypes).sort(),\n\t\tsubjectTypes: () => Array.from(subjectTypes).sort(),\n\t};\n}\n"]}
1
+ {"version":3,"sources":["../events/index.ts"],"names":[],"mappings":";;;AAgCA,IAAM,sBAAA,GAAyB,OAAO,MAAA,CAAO;AAAA,EAC5C,kBAAA;AAAA,EACA,kBAAA;AAAA,EACA;AACD,CAAC,CAAA;AAED,IAAM,oBAAA,GAAuB,OAAO,MAAA,CAAO;AAAA,EAC1C,mBAAA;AAAA,EACA,mBAAA;AAAA,EACA,0BAAA;AAAA,EACA,4BAAA;AAAA,EACA,yBAAA;AAAA,EACA,2BAAA;AAAA,EACA,4BAAA;AAAA,EACA,yBAAA;AAAA,EACA,+BAAA;AAAA,EACA;AACD,CAAC,CAAA;AAeM,SAAS,2BAAA,CAA4B,KAAA,GAA8E,EAAC,EAA0B;AACpJ,EAAA,MAAM,UAAA,mBAAa,IAAI,GAAA,CAAI,CAAC,GAAG,oBAAA,EAAsB,GAAI,KAAA,CAAM,UAAA,IAAc,EAAG,CAAC,CAAA;AACjF,EAAA,MAAM,YAAA,mBAAe,IAAI,GAAA,CAAI,CAAC,GAAG,sBAAA,EAAwB,GAAI,KAAA,CAAM,YAAA,IAAgB,EAAG,CAAC,CAAA;AACvF,EAAA,OAAO;AAAA,IACN,kBAAkB,SAAA,EAAW;AAC5B,MAAA,IAAI,CAAC,SAAA,EAAW;AACf,QAAA,MAAM,IAAI,MAAM,4BAA4B,CAAA;AAAA,MAC7C;AACA,MAAA,UAAA,CAAW,IAAI,SAAS,CAAA;AAAA,IACzB,CAAA;AAAA,IACA,oBAAoB,WAAA,EAAa;AAChC,MAAA,IAAI,CAAC,WAAA,EAAa,MAAM,IAAI,MAAM,8BAA8B,CAAA;AAChE,MAAA,YAAA,CAAa,IAAI,WAAW,CAAA;AAAA,IAC7B,CAAA;AAAA,IACA,YAAA,EAAc,CAAC,SAAA,KAAc,UAAA,CAAW,IAAI,SAAS,CAAA;AAAA,IACrD,cAAA,EAAgB,CAAC,WAAA,KAAgB,YAAA,CAAa,IAAI,WAAW,CAAA;AAAA,IAC7D,YAAY,MAAM,KAAA,CAAM,IAAA,CAAK,UAAU,EAAE,IAAA,EAAK;AAAA,IAC9C,cAAc,MAAM,KAAA,CAAM,IAAA,CAAK,YAAY,EAAE,IAAA;AAAK,GACnD;AACD","file":"chunk-2AE6TMAX.cjs","sourcesContent":["export interface AssetEventEnvelope<TPayload = unknown> {\n\tid: string;\n\ttenantId: string;\n\tspaceId: string;\n\teventType: string;\n\teventSchemaVersion: number;\n\tsubjectType: string;\n\tsubjectId: string;\n\tactorId: string;\n\tactorType: string;\n\tactionInvocationId?: string;\n\tpayload: TPayload;\n\tsequence: number;\n\toccurredAt: Date;\n\trecordedAt: Date;\n\tcorrelationId: string;\n\tcausationId?: string;\n\tprovenance?: EventProvenance;\n\t/**\n\t * Mirrors the emitting action's declared consistency. Present only when the\n\t * action declares `provisional-until-reconciled`, so a consumer can tell a\n\t * settled fact from one still awaiting reconciliation without a lookup.\n\t * Additive and optional: tolerant consumers that ignore it stay correct.\n\t */\n\tconsistency?: \"authoritative-now\" | \"provisional-until-reconciled\";\n}\n\nexport interface EventProvenance {\n\tsource: \"ui\" | \"api\" | \"agent\" | \"worker\" | \"system\" | (string & {});\n\tauditAttributes?: Record<string, string>;\n}\n\nconst BUILT_IN_SUBJECT_TYPES = Object.freeze([\n\t\"ActionInvocation\",\n\t\"PolicyEvaluation\",\n\t\"AdapterInvocation\",\n]);\n\nconst BUILT_IN_EVENT_TYPES = Object.freeze([\n\t\"ComplianceBlocked\",\n\t\"StateTransitioned\",\n\t\"AdapterInvocationStarted\",\n\t\"AdapterInvocationSucceeded\",\n\t\"AdapterInvocationFailed\",\n\t\"ExternalOperationAccepted\",\n\t\"ExternalOperationCompleted\",\n\t\"ExternalOperationFailed\",\n\t\"ExternalOperationContradicted\",\n\t\"WebhookReceived\",\n]);\n\nexport type AssetEventSubjectType = string;\nexport type AssetEventType = string;\nexport type AssetEventActorType = \"natural_person\" | \"agent\" | \"adapter\" | \"system\" | \"service_account\" | \"external_system\" | \"integration\";\n\nexport interface EventContractRegistry {\n\tregisterEventType(eventType: string): void;\n\tregisterSubjectType(subjectType: string): void;\n\thasEventType(eventType: string): boolean;\n\thasSubjectType(subjectType: string): boolean;\n\teventTypes(): string[];\n\tsubjectTypes(): string[];\n}\n\nexport function createEventContractRegistry(input: { eventTypes?: readonly string[]; subjectTypes?: readonly string[] } = {}): EventContractRegistry {\n\tconst eventTypes = new Set([...BUILT_IN_EVENT_TYPES, ...(input.eventTypes ?? [])]);\n\tconst subjectTypes = new Set([...BUILT_IN_SUBJECT_TYPES, ...(input.subjectTypes ?? [])]);\n\treturn {\n\t\tregisterEventType(eventType) {\n\t\t\tif (!eventType) {\n\t\t\t\tthrow new Error(\"Event type cannot be empty\");\n\t\t\t}\n\t\t\teventTypes.add(eventType);\n\t\t},\n\t\tregisterSubjectType(subjectType) {\n\t\t\tif (!subjectType) throw new Error(\"Subject type cannot be empty\");\n\t\t\tsubjectTypes.add(subjectType);\n\t\t},\n\t\thasEventType: (eventType) => eventTypes.has(eventType),\n\t\thasSubjectType: (subjectType) => subjectTypes.has(subjectType),\n\t\teventTypes: () => Array.from(eventTypes).sort(),\n\t\tsubjectTypes: () => Array.from(subjectTypes).sort(),\n\t};\n}\n"]}
@@ -43,5 +43,5 @@ function createActionRegistry(definitions = []) {
43
43
  }
44
44
 
45
45
  export { ACTOR_TYPES, assertActionId, assertActorType, createActionRegistry, isActorType };
46
- //# sourceMappingURL=chunk-4QOA3VU5.js.map
47
- //# sourceMappingURL=chunk-4QOA3VU5.js.map
46
+ //# sourceMappingURL=chunk-2W6FORTE.js.map
47
+ //# sourceMappingURL=chunk-2W6FORTE.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../actions/index.ts"],"names":[],"mappings":";AAwBO,IAAM,WAAA,GAAoC;AAAA,EAChD,gBAAA;AAAA,EACA,OAAA;AAAA,EACA,QAAA;AAAA,EACA,iBAAA;AAAA,EACA,iBAAA;AAAA,EACA;AACD;AAEO,SAAS,YAAY,KAAA,EAAmC;AAC9D,EAAA,OAAQ,WAAA,CAAkC,SAAS,KAAK,CAAA;AACzD;AAEO,SAAS,gBAAgB,KAAA,EAA2C;AAC1E,EAAA,IAAI,CAAC,WAAA,CAAY,KAAK,CAAA,EAAG;AACxB,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,mBAAA,EAAsB,KAAK,CAAA,CAAE,CAAA;AAAA,EAC9C;AACD;AA2KO,SAAS,eAAe,QAAA,EAAgD;AAC9E,EAAA,IAAI,CAAC,oCAAA,CAAqC,IAAA,CAAK,QAAQ,CAAA,EAAG;AACzD,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,mBAAA,EAAsB,QAAQ,CAAA,CAAE,CAAA;AAAA,EACjD;AACD;AAUO,SAAS,oBAAA,CAAoC,WAAA,GAAgD,EAAC,EAAwB;AAC5H,EAAA,MAAM,OAAA,uBAAc,GAAA,EAAqC;AACzD,EAAA,MAAM,QAAA,GAAW,CAAC,UAAA,KAA4C;AAC7D,IAAA,cAAA,CAAe,WAAW,QAAQ,CAAA;AAClC,IAAA,IAAI,OAAA,CAAQ,GAAA,CAAI,UAAA,CAAW,QAAQ,CAAA,EAAG,MAAM,IAAI,KAAA,CAAM,CAAA,QAAA,EAAW,UAAA,CAAW,QAAQ,CAAA,uBAAA,CAAyB,CAAA;AAC7G,IAAA,IAAI,UAAA,CAAW,aAAA,IAAiB,UAAA,CAAW,WAAA,CAAY,WAAW,CAAA,EAAG;AACpE,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,QAAA,EAAW,UAAA,CAAW,QAAQ,CAAA,8FAAA,CAAgG,CAAA;AAAA,IAC/I;AACA,IAAA,OAAA,CAAQ,GAAA,CAAI,UAAA,CAAW,QAAA,EAAU,UAAU,CAAA;AAAA,EAC5C,CAAA;AACA,EAAA,KAAA,MAAW,UAAA,IAAc,WAAA,EAAa,QAAA,CAAS,UAAU,CAAA;AACzD,EAAA,OAAO;AAAA,IACN,QAAA;AAAA,IACA,kBAAkB,UAAA,EAAY;AAC7B,MAAA,IAAI,CAAC,OAAA,CAAQ,GAAA,CAAI,WAAW,QAAQ,CAAA,WAAY,UAAU,CAAA;AAAA,IAC3D,CAAA;AAAA,IACA,OAAA,EAAS,CAAC,QAAA,KAAa,OAAA,CAAQ,IAAI,QAAQ,CAAA;AAAA,IAC3C,GAAA,EAAK,CAAC,QAAA,KAAmC,OAAA,CAAQ,IAAI,QAAoB,CAAA;AAAA,IACzE,KAAK,MAAM,KAAA,CAAM,IAAA,CAAK,OAAA,CAAQ,MAAM;AAAA,GACrC;AACD","file":"chunk-4QOA3VU5.js","sourcesContent":["export type ActionId = `${string}.${string}`;\n\nexport interface SchemaParseIssue {\n\tpath: PropertyKey[];\n\tmessage: string;\n}\n\nexport type SchemaParseResult<T = unknown> =\n\t| { success: true; data: T }\n\t| { success: false; error: { issues: SchemaParseIssue[] } };\n\nexport interface SchemaValidator<T = unknown> {\n\tparse(input: unknown): T;\n\tsafeParse(input: unknown): SchemaParseResult<T>;\n}\n\nexport type ActorType =\n\t| \"natural_person\"\n\t| \"agent\"\n\t| \"system\"\n\t| \"service_account\"\n\t| \"external_system\"\n\t| \"integration\";\n\nexport const ACTOR_TYPES: readonly ActorType[] = [\n\t\"natural_person\",\n\t\"agent\",\n\t\"system\",\n\t\"service_account\",\n\t\"external_system\",\n\t\"integration\",\n] as const;\n\nexport function isActorType(value: string): value is ActorType {\n\treturn (ACTOR_TYPES as readonly string[]).includes(value);\n}\n\nexport function assertActorType(value: string): asserts value is ActorType {\n\tif (!isActorType(value)) {\n\t\tthrow new Error(`Invalid actorType: ${value}`);\n\t}\n}\n\nexport type ActionStatus =\n\t| \"pending\"\n\t| \"running\"\n\t| \"completed\"\n\t| \"failed\"\n\t| \"blocked_by_policy\"\n\t| \"waiting_for_approval\"\n\t| \"reconciliation_required\"\n\t| \"validation_failed\";\n\nexport interface FabricRuntimeServices {\n\treadonly [serviceName: string]: unknown;\n}\n\nexport interface ActionContext<TDb = unknown> {\n\tactionInvocationId: string;\n\ttenantId: string;\n\tspaceId: string;\n\tactorId: string;\n\tactorType: ActorType;\n\tcorrelationId: string;\n\tcausationId?: string;\n\tprovenance?: { source: string; auditAttributes?: Record<string, string> };\n\tdb: TDb;\n\tservices?: FabricRuntimeServices;\n}\n\nexport interface ActionResult {\n\tsuccess: boolean;\n\tdata?: Record<string, unknown>;\n\terror?: string;\n}\n\nexport type ActionHandler<TDb = unknown> = (\n\tctx: ActionContext<TDb>,\n\tparams: unknown,\n) => Promise<ActionResult>;\n\nexport interface AdapterStepRetryPolicy {\n\tidempotent: boolean;\n\tmaxAttempts?: number;\n\tinitialDelayMs?: number;\n\tbackoffMultiplier?: number;\n\tmaxDelayMs?: number;\n}\n\nexport interface AdapterStep {\n\tadapterType: string;\n\toperation: string;\n\tretryPolicy?: AdapterStepRetryPolicy;\n\tgetInput: (\n\t\tparams: unknown,\n\t\thandlerResult: Record<string, unknown>,\n\t) => Record<string, unknown> | undefined;\n}\n\nexport interface ActionStateMachineBinding {\n\tentityType: string;\n\ttargetState: string | ((params: unknown) => string);\n\tgetEntityId: (params: unknown) => string | undefined;\n}\n\nexport interface ActionDefinition<TDb = unknown> {\n\tactionId: ActionId;\n\tnamespace: string;\n\tversion: number;\n\tschema: SchemaValidator;\n\t/** Optional validation contract for the public handler result data. */\n\tresultSchema?: SchemaValidator;\n\thandler?: ActionHandler<TDb>;\n\trequiredRoles?: string[];\n\trequiredPermissions?: string[];\n\tpolicies?: `${string}.v${number}`[];\n\temitsEvents: string[];\n\tidempotent: boolean;\n\tmutatesDomain: boolean;\n\t/** Portable execution semantics used by hosts, gateways, and generated capability contracts. */\n\texecution?: ActionExecutionContract;\n\tstateMachine?: ActionStateMachineBinding;\n\tadapterSteps?: AdapterStep[];\n\t/** Completion actions can attest only after all external adapter work succeeds. */\n\teventPhase?: \"before_adapters\" | \"after_adapters\";\n\t/**\n\t * If \"saga\", the action is a multi-step orchestration. The worker dispatches\n\t * to a registered saga implementation instead of running `handler` directly.\n\t */\n\tkind?: \"atomic\" | \"saga\";\n}\n\nexport type ActionConnectivity = \"online-required\" | \"offline-capturable\";\nexport type AuthorityMoment = \"capture\" | \"execution\" | \"both\";\nexport type ActionIdempotencyStance = \"required\" | \"supported\" | \"prohibited\";\nexport type ActionCompletionMode = \"immediate\" | \"accepted\" | \"long-running\";\nexport type ActionConsistency = \"authoritative-now\" | \"provisional-until-reconciled\";\nexport type ActionDataSensitivity = \"public\" | \"internal\" | \"confidential\" | \"restricted\";\n\nexport interface ActionExecutionContract {\n\tconnectivity: ActionConnectivity;\n\tauthorityMoment: AuthorityMoment;\n\tidempotency: ActionIdempotencyStance;\n\tcompletion: ActionCompletionMode;\n\tconsistency: ActionConsistency;\n\tsensitivity?: ActionDataSensitivity;\n}\n\nexport interface SagaContext {\n\tactionInvocationId: string;\n\ttenantId: string;\n\tspaceId: string;\n\tparameters: unknown;\n\tsleep?: (delayMs: number) => Promise<void>;\n\tquery?: <T = unknown>(model: string, operation: string, args: unknown) => Promise<T>;\n\t/**\n\t * Wait for a named external signal carrying a payload of `T`, with a timeout.\n\t *\n\t * Resolves with the payload of the first signal received, or `null` if the timeout\n\t * fires first. Subsequent signals with the same name received before another\n\t * `awaitSignal` call are buffered (FIFO) so no signal is lost.\n\t *\n\t * Intended for agent-driven and webhook-driven coordination: replace polling loops\n\t * with push-based wakeups while preserving the saga's deterministic replay\n\t * semantics (the runtime is responsible for capturing signals into workflow history).\n\t *\n\t * Optional. Runtimes that cannot implement push-based signaling (e.g. an in-memory\n\t * test harness) may omit this; sagas should treat absence as a fallback condition\n\t * and use `sleep` + `query` polling instead.\n\t *\n\t * Signal *senders* are runtime-specific (e.g. a Temporal `WorkflowClient.signal()`\n\t * call from an action handler). Apps that need to send signals from action\n\t * handlers should expose a coordination service via `ActionContext.services`\n\t * — the platform does not prescribe the sender API.\n\t *\n\t * @example\n\t * const payload = await ctx.awaitSignal?.<{ result: Record<string, unknown> }>(\n\t * \"userInputProcessed\",\n\t * 5 * 60 * 1000,\n\t * );\n\t * if (payload) { /* handle pushed result *\\/ }\n\t * else { /* timeout — fall back to deterministic path *\\/ }\n\t */\n\tawaitSignal?: <T = unknown>(signalName: string, timeoutMs: number) => Promise<T | null>;\n}\n\nexport interface SagaChildActionInput {\n\tsuffix: string;\n\tactionId: string;\n\tparameters: Record<string, unknown>;\n}\n\nexport type SagaRunChild = (input: SagaChildActionInput) => Promise<Record<string, unknown>>;\n\nexport interface SagaCompletionEvent {\n\teventType: string;\n\tsubjectType: string;\n\tsubjectId: string;\n\tpayload: unknown;\n\teventSchemaVersion?: number;\n}\n\nexport interface SagaCompletion {\n\tresultData: Record<string, unknown>;\n\tevent?: SagaCompletionEvent;\n}\n\nexport type SagaImplementation = (\n\tctx: SagaContext,\n\trunChild: SagaRunChild,\n) => Promise<SagaCompletion>;\n\nexport function assertActionId(actionId: string): asserts actionId is ActionId {\n\tif (!/^[a-z][a-z0-9-]*\\.[a-z][a-z0-9_]*$/.test(actionId)) {\n\t\tthrow new Error(`Invalid action ID: ${actionId}`);\n\t}\n}\n\nexport interface ActionRegistry<TDb = unknown> {\n\tregister(definition: ActionDefinition<TDb>): void;\n\tregisterIfMissing(definition: ActionDefinition<TDb>): void;\n\tresolve(actionId: ActionId): ActionDefinition<TDb> | undefined;\n\thas(actionId: string): actionId is ActionId;\n\tids(): ActionId[];\n}\n\nexport function createActionRegistry<TDb = unknown>(definitions: readonly ActionDefinition<TDb>[] = []): ActionRegistry<TDb> {\n\tconst actions = new Map<ActionId, ActionDefinition<TDb>>();\n\tconst register = (definition: ActionDefinition<TDb>): void => {\n\t\tassertActionId(definition.actionId);\n\t\tif (actions.has(definition.actionId)) throw new Error(`Action \"${definition.actionId}\" is already registered`);\n\t\tif (definition.mutatesDomain && definition.emitsEvents.length === 0) {\n\t\t\tthrow new Error(`Action \"${definition.actionId}\" mutates domain but emits no events. Every mutating action must emit at least one AssetEvent.`);\n\t\t}\n\t\tactions.set(definition.actionId, definition);\n\t};\n\tfor (const definition of definitions) register(definition);\n\treturn {\n\t\tregister,\n\t\tregisterIfMissing(definition) {\n\t\t\tif (!actions.has(definition.actionId)) register(definition);\n\t\t},\n\t\tresolve: (actionId) => actions.get(actionId),\n\t\thas: (actionId): actionId is ActionId => actions.has(actionId as ActionId),\n\t\tids: () => Array.from(actions.keys()),\n\t};\n}\n"]}
1
+ {"version":3,"sources":["../actions/index.ts"],"names":[],"mappings":";AAwBO,IAAM,WAAA,GAAoC;AAAA,EAChD,gBAAA;AAAA,EACA,OAAA;AAAA,EACA,QAAA;AAAA,EACA,iBAAA;AAAA,EACA,iBAAA;AAAA,EACA;AACD;AAEO,SAAS,YAAY,KAAA,EAAmC;AAC9D,EAAA,OAAQ,WAAA,CAAkC,SAAS,KAAK,CAAA;AACzD;AAEO,SAAS,gBAAgB,KAAA,EAA2C;AAC1E,EAAA,IAAI,CAAC,WAAA,CAAY,KAAK,CAAA,EAAG;AACxB,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,mBAAA,EAAsB,KAAK,CAAA,CAAE,CAAA;AAAA,EAC9C;AACD;AAyLO,SAAS,eAAe,QAAA,EAAgD;AAC9E,EAAA,IAAI,CAAC,oCAAA,CAAqC,IAAA,CAAK,QAAQ,CAAA,EAAG;AACzD,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,mBAAA,EAAsB,QAAQ,CAAA,CAAE,CAAA;AAAA,EACjD;AACD;AAUO,SAAS,oBAAA,CAAoC,WAAA,GAAgD,EAAC,EAAwB;AAC5H,EAAA,MAAM,OAAA,uBAAc,GAAA,EAAqC;AACzD,EAAA,MAAM,QAAA,GAAW,CAAC,UAAA,KAA4C;AAC7D,IAAA,cAAA,CAAe,WAAW,QAAQ,CAAA;AAClC,IAAA,IAAI,OAAA,CAAQ,GAAA,CAAI,UAAA,CAAW,QAAQ,CAAA,EAAG,MAAM,IAAI,KAAA,CAAM,CAAA,QAAA,EAAW,UAAA,CAAW,QAAQ,CAAA,uBAAA,CAAyB,CAAA;AAC7G,IAAA,IAAI,UAAA,CAAW,aAAA,IAAiB,UAAA,CAAW,WAAA,CAAY,WAAW,CAAA,EAAG;AACpE,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,QAAA,EAAW,UAAA,CAAW,QAAQ,CAAA,8FAAA,CAAgG,CAAA;AAAA,IAC/I;AACA,IAAA,OAAA,CAAQ,GAAA,CAAI,UAAA,CAAW,QAAA,EAAU,UAAU,CAAA;AAAA,EAC5C,CAAA;AACA,EAAA,KAAA,MAAW,UAAA,IAAc,WAAA,EAAa,QAAA,CAAS,UAAU,CAAA;AACzD,EAAA,OAAO;AAAA,IACN,QAAA;AAAA,IACA,kBAAkB,UAAA,EAAY;AAC7B,MAAA,IAAI,CAAC,OAAA,CAAQ,GAAA,CAAI,WAAW,QAAQ,CAAA,WAAY,UAAU,CAAA;AAAA,IAC3D,CAAA;AAAA,IACA,OAAA,EAAS,CAAC,QAAA,KAAa,OAAA,CAAQ,IAAI,QAAQ,CAAA;AAAA,IAC3C,GAAA,EAAK,CAAC,QAAA,KAAmC,OAAA,CAAQ,IAAI,QAAoB,CAAA;AAAA,IACzE,KAAK,MAAM,KAAA,CAAM,IAAA,CAAK,OAAA,CAAQ,MAAM;AAAA,GACrC;AACD","file":"chunk-2W6FORTE.js","sourcesContent":["export type ActionId = `${string}.${string}`;\n\nexport interface SchemaParseIssue {\n\tpath: PropertyKey[];\n\tmessage: string;\n}\n\nexport type SchemaParseResult<T = unknown> =\n\t| { success: true; data: T }\n\t| { success: false; error: { issues: SchemaParseIssue[] } };\n\nexport interface SchemaValidator<T = unknown> {\n\tparse(input: unknown): T;\n\tsafeParse(input: unknown): SchemaParseResult<T>;\n}\n\nexport type ActorType =\n\t| \"natural_person\"\n\t| \"agent\"\n\t| \"system\"\n\t| \"service_account\"\n\t| \"external_system\"\n\t| \"integration\";\n\nexport const ACTOR_TYPES: readonly ActorType[] = [\n\t\"natural_person\",\n\t\"agent\",\n\t\"system\",\n\t\"service_account\",\n\t\"external_system\",\n\t\"integration\",\n] as const;\n\nexport function isActorType(value: string): value is ActorType {\n\treturn (ACTOR_TYPES as readonly string[]).includes(value);\n}\n\nexport function assertActorType(value: string): asserts value is ActorType {\n\tif (!isActorType(value)) {\n\t\tthrow new Error(`Invalid actorType: ${value}`);\n\t}\n}\n\nexport type ActionStatus =\n\t| \"pending\"\n\t| \"running\"\n\t| \"completed\"\n\t| \"failed\"\n\t| \"blocked_by_policy\"\n\t| \"waiting_for_approval\"\n\t| \"reconciliation_required\"\n\t| \"validation_failed\";\n\nexport interface FabricRuntimeServices {\n\treadonly [serviceName: string]: unknown;\n}\n\nexport interface ActionContext<TDb = unknown> {\n\tactionInvocationId: string;\n\ttenantId: string;\n\tspaceId: string;\n\tactorId: string;\n\tactorType: ActorType;\n\tcorrelationId: string;\n\tcausationId?: string;\n\tprovenance?: { source: string; auditAttributes?: Record<string, string> };\n\tdb: TDb;\n\tservices?: FabricRuntimeServices;\n}\n\nexport interface ActionResult {\n\tsuccess: boolean;\n\tdata?: Record<string, unknown>;\n\terror?: string;\n}\n\nexport type ActionHandler<TDb = unknown> = (\n\tctx: ActionContext<TDb>,\n\tparams: unknown,\n) => Promise<ActionResult>;\n\nexport interface AdapterStepRetryPolicy {\n\tidempotent: boolean;\n\tmaxAttempts?: number;\n\tinitialDelayMs?: number;\n\tbackoffMultiplier?: number;\n\tmaxDelayMs?: number;\n}\n\nexport interface AdapterStep {\n\tadapterType: string;\n\toperation: string;\n\tretryPolicy?: AdapterStepRetryPolicy;\n\tgetInput: (\n\t\tparams: unknown,\n\t\thandlerResult: Record<string, unknown>,\n\t) => Record<string, unknown> | undefined;\n}\n\nexport interface ActionStateMachineBinding {\n\tentityType: string;\n\ttargetState: string | ((params: unknown) => string);\n\tgetEntityId: (params: unknown) => string | undefined;\n}\n\nexport interface ActionDefinition<TDb = unknown> {\n\tactionId: ActionId;\n\tnamespace: string;\n\tversion: number;\n\tschema: SchemaValidator;\n\t/** Optional validation contract for the public handler result data. */\n\tresultSchema?: SchemaValidator;\n\thandler?: ActionHandler<TDb>;\n\trequiredRoles?: string[];\n\trequiredPermissions?: string[];\n\tpolicies?: `${string}.v${number}`[];\n\temitsEvents: string[];\n\tidempotent: boolean;\n\tmutatesDomain: boolean;\n\t/** Portable execution semantics used by hosts, gateways, and generated capability contracts. */\n\texecution?: ActionExecutionContract;\n\tstateMachine?: ActionStateMachineBinding;\n\tadapterSteps?: AdapterStep[];\n\t/** Completion actions can attest only after all external adapter work succeeds. */\n\teventPhase?: \"before_adapters\" | \"after_adapters\";\n\t/**\n\t * If \"saga\", the action is a multi-step orchestration. The worker dispatches\n\t * to a registered saga implementation instead of running `handler` directly.\n\t */\n\tkind?: \"atomic\" | \"saga\";\n}\n\nexport type ActionConnectivity = \"online-required\" | \"offline-capturable\";\nexport type AuthorityMoment = \"capture\" | \"execution\" | \"both\";\nexport type ActionIdempotencyStance = \"required\" | \"supported\" | \"prohibited\";\nexport type ActionCompletionMode = \"immediate\" | \"accepted\" | \"long-running\";\nexport type ActionConsistency = \"authoritative-now\" | \"provisional-until-reconciled\";\nexport type ActionDataSensitivity = \"public\" | \"internal\" | \"confidential\" | \"restricted\";\n\nexport interface ActionExecutionContract {\n\tconnectivity: ActionConnectivity;\n\tauthorityMoment: AuthorityMoment;\n\tidempotency: ActionIdempotencyStance;\n\t/**\n\t * `immediate`: the invocation settles within the host's execution.\n\t * `accepted` and `long-running`: an adapter may hand the work to an\n\t * external system and the invocation stays running until that system\n\t * completes it by reference through the host's completion ingress.\n\t * Declare `completionDeadlineMs` on a `long-running` action so a callback\n\t * that never comes is noticed rather than waited on forever.\n\t */\n\tcompletion: ActionCompletionMode;\n\t/**\n\t * How long an accepted handoff may wait for its completion before the host\n\t * moves the invocation to reconciliation. Without it, nothing sweeps the\n\t * handoff. Refused on `immediate`, since nothing external completes it.\n\t */\n\tcompletionDeadlineMs?: number;\n\tconsistency: ActionConsistency;\n\tsensitivity?: ActionDataSensitivity;\n}\n\nexport interface SagaContext {\n\tactionInvocationId: string;\n\ttenantId: string;\n\tspaceId: string;\n\tparameters: unknown;\n\tsleep?: (delayMs: number) => Promise<void>;\n\tquery?: <T = unknown>(model: string, operation: string, args: unknown) => Promise<T>;\n\t/**\n\t * Wait for a named external signal carrying a payload of `T`, with a timeout.\n\t *\n\t * Resolves with the payload of the first signal received, or `null` if the timeout\n\t * fires first. Subsequent signals with the same name received before another\n\t * `awaitSignal` call are buffered (FIFO) so no signal is lost.\n\t *\n\t * Intended for agent-driven and webhook-driven coordination: replace polling loops\n\t * with push-based wakeups while preserving the saga's deterministic replay\n\t * semantics (the runtime is responsible for capturing signals into workflow history).\n\t *\n\t * Optional. Runtimes that cannot implement push-based signaling (e.g. an in-memory\n\t * test harness) may omit this; sagas should treat absence as a fallback condition\n\t * and use `sleep` + `query` polling instead.\n\t *\n\t * Signal *senders* are runtime-specific (e.g. a Temporal `WorkflowClient.signal()`\n\t * call from an action handler). Apps that need to send signals from action\n\t * handlers should expose a coordination service via `ActionContext.services`\n\t * — the platform does not prescribe the sender API.\n\t *\n\t * @example\n\t * const payload = await ctx.awaitSignal?.<{ result: Record<string, unknown> }>(\n\t * \"userInputProcessed\",\n\t * 5 * 60 * 1000,\n\t * );\n\t * if (payload) { /* handle pushed result *\\/ }\n\t * else { /* timeout — fall back to deterministic path *\\/ }\n\t */\n\tawaitSignal?: <T = unknown>(signalName: string, timeoutMs: number) => Promise<T | null>;\n}\n\nexport interface SagaChildActionInput {\n\tsuffix: string;\n\tactionId: string;\n\tparameters: Record<string, unknown>;\n}\n\nexport type SagaRunChild = (input: SagaChildActionInput) => Promise<Record<string, unknown>>;\n\nexport interface SagaCompletionEvent {\n\teventType: string;\n\tsubjectType: string;\n\tsubjectId: string;\n\tpayload: unknown;\n\teventSchemaVersion?: number;\n}\n\nexport interface SagaCompletion {\n\tresultData: Record<string, unknown>;\n\tevent?: SagaCompletionEvent;\n}\n\nexport type SagaImplementation = (\n\tctx: SagaContext,\n\trunChild: SagaRunChild,\n) => Promise<SagaCompletion>;\n\nexport function assertActionId(actionId: string): asserts actionId is ActionId {\n\tif (!/^[a-z][a-z0-9-]*\\.[a-z][a-z0-9_]*$/.test(actionId)) {\n\t\tthrow new Error(`Invalid action ID: ${actionId}`);\n\t}\n}\n\nexport interface ActionRegistry<TDb = unknown> {\n\tregister(definition: ActionDefinition<TDb>): void;\n\tregisterIfMissing(definition: ActionDefinition<TDb>): void;\n\tresolve(actionId: ActionId): ActionDefinition<TDb> | undefined;\n\thas(actionId: string): actionId is ActionId;\n\tids(): ActionId[];\n}\n\nexport function createActionRegistry<TDb = unknown>(definitions: readonly ActionDefinition<TDb>[] = []): ActionRegistry<TDb> {\n\tconst actions = new Map<ActionId, ActionDefinition<TDb>>();\n\tconst register = (definition: ActionDefinition<TDb>): void => {\n\t\tassertActionId(definition.actionId);\n\t\tif (actions.has(definition.actionId)) throw new Error(`Action \"${definition.actionId}\" is already registered`);\n\t\tif (definition.mutatesDomain && definition.emitsEvents.length === 0) {\n\t\t\tthrow new Error(`Action \"${definition.actionId}\" mutates domain but emits no events. Every mutating action must emit at least one AssetEvent.`);\n\t\t}\n\t\tactions.set(definition.actionId, definition);\n\t};\n\tfor (const definition of definitions) register(definition);\n\treturn {\n\t\tregister,\n\t\tregisterIfMissing(definition) {\n\t\t\tif (!actions.has(definition.actionId)) register(definition);\n\t\t},\n\t\tresolve: (actionId) => actions.get(actionId),\n\t\thas: (actionId): actionId is ActionId => actions.has(actionId as ActionId),\n\t\tids: () => Array.from(actions.keys()),\n\t};\n}\n"]}
@@ -10,6 +10,10 @@ var BUILT_IN_EVENT_TYPES = Object.freeze([
10
10
  "AdapterInvocationStarted",
11
11
  "AdapterInvocationSucceeded",
12
12
  "AdapterInvocationFailed",
13
+ "ExternalOperationAccepted",
14
+ "ExternalOperationCompleted",
15
+ "ExternalOperationFailed",
16
+ "ExternalOperationContradicted",
13
17
  "WebhookReceived"
14
18
  ]);
15
19
  function createEventContractRegistry(input = {}) {
@@ -34,5 +38,5 @@ function createEventContractRegistry(input = {}) {
34
38
  }
35
39
 
36
40
  export { createEventContractRegistry };
37
- //# sourceMappingURL=chunk-NHGBTPPE.js.map
38
- //# sourceMappingURL=chunk-NHGBTPPE.js.map
41
+ //# sourceMappingURL=chunk-B5DOGDPG.js.map
42
+ //# sourceMappingURL=chunk-B5DOGDPG.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../events/index.ts"],"names":[],"mappings":";AAgCA,IAAM,sBAAA,GAAyB,OAAO,MAAA,CAAO;AAAA,EAC5C,kBAAA;AAAA,EACA,kBAAA;AAAA,EACA;AACD,CAAC,CAAA;AAED,IAAM,oBAAA,GAAuB,OAAO,MAAA,CAAO;AAAA,EAC1C,mBAAA;AAAA,EACA,mBAAA;AAAA,EACA,0BAAA;AAAA,EACA,4BAAA;AAAA,EACA,yBAAA;AAAA,EACA;AACD,CAAC,CAAA;AAeM,SAAS,2BAAA,CAA4B,KAAA,GAA8E,EAAC,EAA0B;AACpJ,EAAA,MAAM,UAAA,mBAAa,IAAI,GAAA,CAAI,CAAC,GAAG,oBAAA,EAAsB,GAAI,KAAA,CAAM,UAAA,IAAc,EAAG,CAAC,CAAA;AACjF,EAAA,MAAM,YAAA,mBAAe,IAAI,GAAA,CAAI,CAAC,GAAG,sBAAA,EAAwB,GAAI,KAAA,CAAM,YAAA,IAAgB,EAAG,CAAC,CAAA;AACvF,EAAA,OAAO;AAAA,IACN,kBAAkB,SAAA,EAAW;AAC5B,MAAA,IAAI,CAAC,SAAA,EAAW;AACf,QAAA,MAAM,IAAI,MAAM,4BAA4B,CAAA;AAAA,MAC7C;AACA,MAAA,UAAA,CAAW,IAAI,SAAS,CAAA;AAAA,IACzB,CAAA;AAAA,IACA,oBAAoB,WAAA,EAAa;AAChC,MAAA,IAAI,CAAC,WAAA,EAAa,MAAM,IAAI,MAAM,8BAA8B,CAAA;AAChE,MAAA,YAAA,CAAa,IAAI,WAAW,CAAA;AAAA,IAC7B,CAAA;AAAA,IACA,YAAA,EAAc,CAAC,SAAA,KAAc,UAAA,CAAW,IAAI,SAAS,CAAA;AAAA,IACrD,cAAA,EAAgB,CAAC,WAAA,KAAgB,YAAA,CAAa,IAAI,WAAW,CAAA;AAAA,IAC7D,YAAY,MAAM,KAAA,CAAM,IAAA,CAAK,UAAU,EAAE,IAAA,EAAK;AAAA,IAC9C,cAAc,MAAM,KAAA,CAAM,IAAA,CAAK,YAAY,EAAE,IAAA;AAAK,GACnD;AACD","file":"chunk-NHGBTPPE.js","sourcesContent":["export interface AssetEventEnvelope<TPayload = unknown> {\n\tid: string;\n\ttenantId: string;\n\tspaceId: string;\n\teventType: string;\n\teventSchemaVersion: number;\n\tsubjectType: string;\n\tsubjectId: string;\n\tactorId: string;\n\tactorType: string;\n\tactionInvocationId?: string;\n\tpayload: TPayload;\n\tsequence: number;\n\toccurredAt: Date;\n\trecordedAt: Date;\n\tcorrelationId: string;\n\tcausationId?: string;\n\tprovenance?: EventProvenance;\n\t/**\n\t * Mirrors the emitting action's declared consistency. Present only when the\n\t * action declares `provisional-until-reconciled`, so a consumer can tell a\n\t * settled fact from one still awaiting reconciliation without a lookup.\n\t * Additive and optional: tolerant consumers that ignore it stay correct.\n\t */\n\tconsistency?: \"authoritative-now\" | \"provisional-until-reconciled\";\n}\n\nexport interface EventProvenance {\n\tsource: \"ui\" | \"api\" | \"agent\" | \"worker\" | \"system\" | (string & {});\n\tauditAttributes?: Record<string, string>;\n}\n\nconst BUILT_IN_SUBJECT_TYPES = Object.freeze([\n\t\"ActionInvocation\",\n\t\"PolicyEvaluation\",\n\t\"AdapterInvocation\",\n]);\n\nconst BUILT_IN_EVENT_TYPES = Object.freeze([\n\t\"ComplianceBlocked\",\n\t\"StateTransitioned\",\n\t\"AdapterInvocationStarted\",\n\t\"AdapterInvocationSucceeded\",\n\t\"AdapterInvocationFailed\",\n\t\"WebhookReceived\",\n]);\n\nexport type AssetEventSubjectType = string;\nexport type AssetEventType = string;\nexport type AssetEventActorType = \"natural_person\" | \"agent\" | \"adapter\" | \"system\" | \"service_account\" | \"external_system\" | \"integration\";\n\nexport interface EventContractRegistry {\n\tregisterEventType(eventType: string): void;\n\tregisterSubjectType(subjectType: string): void;\n\thasEventType(eventType: string): boolean;\n\thasSubjectType(subjectType: string): boolean;\n\teventTypes(): string[];\n\tsubjectTypes(): string[];\n}\n\nexport function createEventContractRegistry(input: { eventTypes?: readonly string[]; subjectTypes?: readonly string[] } = {}): EventContractRegistry {\n\tconst eventTypes = new Set([...BUILT_IN_EVENT_TYPES, ...(input.eventTypes ?? [])]);\n\tconst subjectTypes = new Set([...BUILT_IN_SUBJECT_TYPES, ...(input.subjectTypes ?? [])]);\n\treturn {\n\t\tregisterEventType(eventType) {\n\t\t\tif (!eventType) {\n\t\t\t\tthrow new Error(\"Event type cannot be empty\");\n\t\t\t}\n\t\t\teventTypes.add(eventType);\n\t\t},\n\t\tregisterSubjectType(subjectType) {\n\t\t\tif (!subjectType) throw new Error(\"Subject type cannot be empty\");\n\t\t\tsubjectTypes.add(subjectType);\n\t\t},\n\t\thasEventType: (eventType) => eventTypes.has(eventType),\n\t\thasSubjectType: (subjectType) => subjectTypes.has(subjectType),\n\t\teventTypes: () => Array.from(eventTypes).sort(),\n\t\tsubjectTypes: () => Array.from(subjectTypes).sort(),\n\t};\n}\n"]}
1
+ {"version":3,"sources":["../events/index.ts"],"names":[],"mappings":";AAgCA,IAAM,sBAAA,GAAyB,OAAO,MAAA,CAAO;AAAA,EAC5C,kBAAA;AAAA,EACA,kBAAA;AAAA,EACA;AACD,CAAC,CAAA;AAED,IAAM,oBAAA,GAAuB,OAAO,MAAA,CAAO;AAAA,EAC1C,mBAAA;AAAA,EACA,mBAAA;AAAA,EACA,0BAAA;AAAA,EACA,4BAAA;AAAA,EACA,yBAAA;AAAA,EACA,2BAAA;AAAA,EACA,4BAAA;AAAA,EACA,yBAAA;AAAA,EACA,+BAAA;AAAA,EACA;AACD,CAAC,CAAA;AAeM,SAAS,2BAAA,CAA4B,KAAA,GAA8E,EAAC,EAA0B;AACpJ,EAAA,MAAM,UAAA,mBAAa,IAAI,GAAA,CAAI,CAAC,GAAG,oBAAA,EAAsB,GAAI,KAAA,CAAM,UAAA,IAAc,EAAG,CAAC,CAAA;AACjF,EAAA,MAAM,YAAA,mBAAe,IAAI,GAAA,CAAI,CAAC,GAAG,sBAAA,EAAwB,GAAI,KAAA,CAAM,YAAA,IAAgB,EAAG,CAAC,CAAA;AACvF,EAAA,OAAO;AAAA,IACN,kBAAkB,SAAA,EAAW;AAC5B,MAAA,IAAI,CAAC,SAAA,EAAW;AACf,QAAA,MAAM,IAAI,MAAM,4BAA4B,CAAA;AAAA,MAC7C;AACA,MAAA,UAAA,CAAW,IAAI,SAAS,CAAA;AAAA,IACzB,CAAA;AAAA,IACA,oBAAoB,WAAA,EAAa;AAChC,MAAA,IAAI,CAAC,WAAA,EAAa,MAAM,IAAI,MAAM,8BAA8B,CAAA;AAChE,MAAA,YAAA,CAAa,IAAI,WAAW,CAAA;AAAA,IAC7B,CAAA;AAAA,IACA,YAAA,EAAc,CAAC,SAAA,KAAc,UAAA,CAAW,IAAI,SAAS,CAAA;AAAA,IACrD,cAAA,EAAgB,CAAC,WAAA,KAAgB,YAAA,CAAa,IAAI,WAAW,CAAA;AAAA,IAC7D,YAAY,MAAM,KAAA,CAAM,IAAA,CAAK,UAAU,EAAE,IAAA,EAAK;AAAA,IAC9C,cAAc,MAAM,KAAA,CAAM,IAAA,CAAK,YAAY,EAAE,IAAA;AAAK,GACnD;AACD","file":"chunk-B5DOGDPG.js","sourcesContent":["export interface AssetEventEnvelope<TPayload = unknown> {\n\tid: string;\n\ttenantId: string;\n\tspaceId: string;\n\teventType: string;\n\teventSchemaVersion: number;\n\tsubjectType: string;\n\tsubjectId: string;\n\tactorId: string;\n\tactorType: string;\n\tactionInvocationId?: string;\n\tpayload: TPayload;\n\tsequence: number;\n\toccurredAt: Date;\n\trecordedAt: Date;\n\tcorrelationId: string;\n\tcausationId?: string;\n\tprovenance?: EventProvenance;\n\t/**\n\t * Mirrors the emitting action's declared consistency. Present only when the\n\t * action declares `provisional-until-reconciled`, so a consumer can tell a\n\t * settled fact from one still awaiting reconciliation without a lookup.\n\t * Additive and optional: tolerant consumers that ignore it stay correct.\n\t */\n\tconsistency?: \"authoritative-now\" | \"provisional-until-reconciled\";\n}\n\nexport interface EventProvenance {\n\tsource: \"ui\" | \"api\" | \"agent\" | \"worker\" | \"system\" | (string & {});\n\tauditAttributes?: Record<string, string>;\n}\n\nconst BUILT_IN_SUBJECT_TYPES = Object.freeze([\n\t\"ActionInvocation\",\n\t\"PolicyEvaluation\",\n\t\"AdapterInvocation\",\n]);\n\nconst BUILT_IN_EVENT_TYPES = Object.freeze([\n\t\"ComplianceBlocked\",\n\t\"StateTransitioned\",\n\t\"AdapterInvocationStarted\",\n\t\"AdapterInvocationSucceeded\",\n\t\"AdapterInvocationFailed\",\n\t\"ExternalOperationAccepted\",\n\t\"ExternalOperationCompleted\",\n\t\"ExternalOperationFailed\",\n\t\"ExternalOperationContradicted\",\n\t\"WebhookReceived\",\n]);\n\nexport type AssetEventSubjectType = string;\nexport type AssetEventType = string;\nexport type AssetEventActorType = \"natural_person\" | \"agent\" | \"adapter\" | \"system\" | \"service_account\" | \"external_system\" | \"integration\";\n\nexport interface EventContractRegistry {\n\tregisterEventType(eventType: string): void;\n\tregisterSubjectType(subjectType: string): void;\n\thasEventType(eventType: string): boolean;\n\thasSubjectType(subjectType: string): boolean;\n\teventTypes(): string[];\n\tsubjectTypes(): string[];\n}\n\nexport function createEventContractRegistry(input: { eventTypes?: readonly string[]; subjectTypes?: readonly string[] } = {}): EventContractRegistry {\n\tconst eventTypes = new Set([...BUILT_IN_EVENT_TYPES, ...(input.eventTypes ?? [])]);\n\tconst subjectTypes = new Set([...BUILT_IN_SUBJECT_TYPES, ...(input.subjectTypes ?? [])]);\n\treturn {\n\t\tregisterEventType(eventType) {\n\t\t\tif (!eventType) {\n\t\t\t\tthrow new Error(\"Event type cannot be empty\");\n\t\t\t}\n\t\t\teventTypes.add(eventType);\n\t\t},\n\t\tregisterSubjectType(subjectType) {\n\t\t\tif (!subjectType) throw new Error(\"Subject type cannot be empty\");\n\t\t\tsubjectTypes.add(subjectType);\n\t\t},\n\t\thasEventType: (eventType) => eventTypes.has(eventType),\n\t\thasSubjectType: (subjectType) => subjectTypes.has(subjectType),\n\t\teventTypes: () => Array.from(eventTypes).sort(),\n\t\tsubjectTypes: () => Array.from(subjectTypes).sort(),\n\t};\n}\n"]}
@@ -1,4 +1,4 @@
1
- import { AdapterRegistry } from './chunk-DTY3CHQZ.js';
1
+ import { AdapterRegistry } from './chunk-FAG2RTPM.js';
2
2
 
3
3
  // testing/index.ts
4
4
  function createFakeActionContext(options = {}) {
@@ -23,5 +23,5 @@ function createDeterministicIdFactory(prefix = "test") {
23
23
  }
24
24
 
25
25
  export { createDeterministicIdFactory, createFakeActionContext, createInMemoryAdapterRegistry };
26
- //# sourceMappingURL=chunk-AWP6JDD5.js.map
27
- //# sourceMappingURL=chunk-AWP6JDD5.js.map
26
+ //# sourceMappingURL=chunk-DCC3UIUJ.js.map
27
+ //# sourceMappingURL=chunk-DCC3UIUJ.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../testing/index.ts"],"names":[],"mappings":";;;AAeO,SAAS,uBAAA,CACf,OAAA,GAAyC,EAAC,EACrB;AACrB,EAAA,OAAO;AAAA,IACN,kBAAA,EAAoB,QAAQ,kBAAA,IAAsB,UAAA;AAAA,IAClD,QAAA,EAAU,QAAQ,QAAA,IAAY,aAAA;AAAA,IAC9B,OAAA,EAAS,QAAQ,OAAA,IAAW,YAAA;AAAA,IAC5B,OAAA,EAAS,QAAQ,OAAA,IAAW,YAAA;AAAA,IAC5B,SAAA,EAAW,QAAQ,SAAA,IAAa,QAAA;AAAA,IAChC,aAAA,EAAe,QAAQ,aAAA,IAAiB,WAAA;AAAA,IACxC,aAAa,OAAA,CAAQ,WAAA;AAAA,IACrB,EAAA,EAAI,OAAA,CAAQ,EAAA,IAAO,EAAC;AAAA,IACpB,QAAA,EAAU,OAAA,CAAQ,QAAA,IAAY;AAAC,GAChC;AACD;AAEO,SAAS,6BAAA,GAAiD;AAChE,EAAA,OAAO,IAAI,eAAA,EAAgB;AAC5B;AAEO,SAAS,4BAAA,CAA6B,SAAS,MAAA,EAAsB;AAC3E,EAAA,IAAI,QAAA,GAAW,CAAA;AACf,EAAA,OAAO,MAAM,CAAA,EAAG,MAAM,CAAA,CAAA,EAAI,MAAA,CAAO,EAAE,QAAQ,CAAA,CAAE,QAAA,CAAS,CAAA,EAAG,GAAG,CAAC,CAAA,CAAA;AAC9D","file":"chunk-AWP6JDD5.js","sourcesContent":["import { AdapterRegistry } from \"../adapters\";\nimport type { ActionContext, ActorType } from \"../actions\";\n\nexport interface FakeActionContextOptions<TDb = Record<string, never>> {\n\tactionInvocationId?: string;\n\ttenantId?: string;\n\tspaceId?: string;\n\tactorId?: string;\n\tactorType?: ActorType;\n\tcorrelationId?: string;\n\tcausationId?: string;\n\tdb?: TDb;\n\tservices?: Record<string, unknown>;\n}\n\nexport function createFakeActionContext<TDb = Record<string, never>>(\n\toptions: FakeActionContextOptions<TDb> = {},\n): ActionContext<TDb> {\n\treturn {\n\t\tactionInvocationId: options.actionInvocationId ?? \"act_test\",\n\t\ttenantId: options.tenantId ?? \"tenant-test\",\n\t\tspaceId: options.spaceId ?? \"space-test\",\n\t\tactorId: options.actorId ?? \"actor-test\",\n\t\tactorType: options.actorType ?? \"system\",\n\t\tcorrelationId: options.correlationId ?? \"corr-test\",\n\t\tcausationId: options.causationId,\n\t\tdb: options.db ?? ({} as TDb),\n\t\tservices: options.services ?? {},\n\t};\n}\n\nexport function createInMemoryAdapterRegistry(): AdapterRegistry {\n\treturn new AdapterRegistry();\n}\n\nexport function createDeterministicIdFactory(prefix = \"test\"): () => string {\n\tlet sequence = 0;\n\treturn () => `${prefix}_${String(++sequence).padStart(6, \"0\")}`;\n}\n"]}
1
+ {"version":3,"sources":["../testing/index.ts"],"names":[],"mappings":";;;AAeO,SAAS,uBAAA,CACf,OAAA,GAAyC,EAAC,EACrB;AACrB,EAAA,OAAO;AAAA,IACN,kBAAA,EAAoB,QAAQ,kBAAA,IAAsB,UAAA;AAAA,IAClD,QAAA,EAAU,QAAQ,QAAA,IAAY,aAAA;AAAA,IAC9B,OAAA,EAAS,QAAQ,OAAA,IAAW,YAAA;AAAA,IAC5B,OAAA,EAAS,QAAQ,OAAA,IAAW,YAAA;AAAA,IAC5B,SAAA,EAAW,QAAQ,SAAA,IAAa,QAAA;AAAA,IAChC,aAAA,EAAe,QAAQ,aAAA,IAAiB,WAAA;AAAA,IACxC,aAAa,OAAA,CAAQ,WAAA;AAAA,IACrB,EAAA,EAAI,OAAA,CAAQ,EAAA,IAAO,EAAC;AAAA,IACpB,QAAA,EAAU,OAAA,CAAQ,QAAA,IAAY;AAAC,GAChC;AACD;AAEO,SAAS,6BAAA,GAAiD;AAChE,EAAA,OAAO,IAAI,eAAA,EAAgB;AAC5B;AAEO,SAAS,4BAAA,CAA6B,SAAS,MAAA,EAAsB;AAC3E,EAAA,IAAI,QAAA,GAAW,CAAA;AACf,EAAA,OAAO,MAAM,CAAA,EAAG,MAAM,CAAA,CAAA,EAAI,MAAA,CAAO,EAAE,QAAQ,CAAA,CAAE,QAAA,CAAS,CAAA,EAAG,GAAG,CAAC,CAAA,CAAA;AAC9D","file":"chunk-DCC3UIUJ.js","sourcesContent":["import { AdapterRegistry } from \"../adapters\";\nimport type { ActionContext, ActorType } from \"../actions\";\n\nexport interface FakeActionContextOptions<TDb = Record<string, never>> {\n\tactionInvocationId?: string;\n\ttenantId?: string;\n\tspaceId?: string;\n\tactorId?: string;\n\tactorType?: ActorType;\n\tcorrelationId?: string;\n\tcausationId?: string;\n\tdb?: TDb;\n\tservices?: Record<string, unknown>;\n}\n\nexport function createFakeActionContext<TDb = Record<string, never>>(\n\toptions: FakeActionContextOptions<TDb> = {},\n): ActionContext<TDb> {\n\treturn {\n\t\tactionInvocationId: options.actionInvocationId ?? \"act_test\",\n\t\ttenantId: options.tenantId ?? \"tenant-test\",\n\t\tspaceId: options.spaceId ?? \"space-test\",\n\t\tactorId: options.actorId ?? \"actor-test\",\n\t\tactorType: options.actorType ?? \"system\",\n\t\tcorrelationId: options.correlationId ?? \"corr-test\",\n\t\tcausationId: options.causationId,\n\t\tdb: options.db ?? ({} as TDb),\n\t\tservices: options.services ?? {},\n\t};\n}\n\nexport function createInMemoryAdapterRegistry(): AdapterRegistry {\n\treturn new AdapterRegistry();\n}\n\nexport function createDeterministicIdFactory(prefix = \"test\"): () => string {\n\tlet sequence = 0;\n\treturn () => `${prefix}_${String(++sequence).padStart(6, \"0\")}`;\n}\n"]}
@@ -116,5 +116,5 @@ async function executeWithAdapterRetry(options) {
116
116
  }
117
117
 
118
118
  export { AdapterRegistry, MissingAdapterRegistrationError, assertAdapterOutcomeConsistency, classifyAdapterOutcome, executeWithAdapterRetry, getRetryDelayMs, resolveAdapterRetryPolicy, shouldRetryAdapterOutcome };
119
- //# sourceMappingURL=chunk-DTY3CHQZ.js.map
120
- //# sourceMappingURL=chunk-DTY3CHQZ.js.map
119
+ //# sourceMappingURL=chunk-FAG2RTPM.js.map
120
+ //# sourceMappingURL=chunk-FAG2RTPM.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../adapters/index.ts"],"names":[],"mappings":";AA+JA,SAAS,UAAA,CAAW,aAAqB,SAAA,EAA2B;AACnE,EAAA,OAAO,CAAA,EAAG,WAAW,CAAA,CAAA,EAAI,SAAS,CAAA,CAAA;AACnC;AAEO,IAAM,+BAAA,GAAN,cAA8C,KAAA,CAAM;AAAA,EAC1D,WAAA,CAAY,aAAqB,SAAA,EAAmB;AACnD,IAAA,KAAA,CAAM,CAAA,uCAAA,EAA0C,WAAW,CAAA,iBAAA,EAAoB,SAAS,CAAA,CAAA,CAAG,CAAA;AAC3F,IAAA,IAAA,CAAK,IAAA,GAAO,iCAAA;AAAA,EACb;AACD;AAEO,IAAM,kBAAN,MAAsB;AAAA,EACX,QAAA,uBAAe,GAAA,EAAmC;AAAA,EAEnE,SAAS,OAAA,EAAsC;AAC9C,IAAA,MAAM,GAAA,GAAM,UAAA,CAAW,OAAA,CAAQ,WAAA,EAAa,QAAQ,SAAS,CAAA;AAC7D,IAAA,IAAI,IAAA,CAAK,QAAA,CAAS,GAAA,CAAI,GAAG,CAAA,EAAG;AAC3B,MAAA,MAAM,IAAI,KAAA;AAAA,QACT,CAAA,4CAAA,EAA+C,OAAA,CAAQ,WAAW,CAAA,iBAAA,EAAoB,QAAQ,SAAS,CAAA,CAAA;AAAA,OACxG;AAAA,IACD;AAEA,IAAA,IAAA,CAAK,QAAA,CAAS,GAAA,CAAI,GAAA,EAAK,OAAO,CAAA;AAAA,EAC/B;AAAA,EAEA,OAAA,CAAQ,aAAqB,SAAA,EAAsD;AAClF,IAAA,OAAO,KAAK,QAAA,CAAS,GAAA,CAAI,UAAA,CAAW,WAAA,EAAa,SAAS,CAAC,CAAA;AAAA,EAC5D;AAAA,EAEA,OAAA,CAAQ,aAAqB,SAAA,EAA0C;AACtE,IAAA,MAAM,OAAA,GAAU,IAAA,CAAK,OAAA,CAAQ,WAAA,EAAa,SAAS,CAAA;AACnD,IAAA,IAAI,CAAC,OAAA,EAAS;AACb,MAAA,MAAM,IAAI,+BAAA,CAAgC,WAAA,EAAa,SAAS,CAAA;AAAA,IACjE;AAEA,IAAA,OAAO,OAAA;AAAA,EACR;AACD;AAEA,IAAM,oBAAA,GAAmD;AAAA,EAExD,WAAA,EAAa,CAAA;AAAA,EACb,cAAA,EAAgB,GAAA;AAAA,EAChB,iBAAA,EAAmB,CAAA;AAAA,EACnB,UAAA,EAAY;AACb,CAAA;AAEA,IAAM,eAAA,GAA8C;AAAA,EACnD,UAAA,EAAY,KAAA;AAAA,EACZ,WAAA,EAAa,CAAA;AAAA,EACb,cAAA,EAAgB,CAAA;AAAA,EAChB,iBAAA,EAAmB,CAAA;AAAA,EACnB,UAAA,EAAY;AACb,CAAA;AAEO,SAAS,yBAAA,CACf,QACA,iBAAA,EAC6B;AAC7B,EAAA,MAAM,UAAA,GAAa,QAAQ,UAAA,IAAc,iBAAA;AAEzC,EAAA,IAAI,CAAC,UAAA,EAAY;AAChB,IAAA,OAAO,eAAA;AAAA,EACR;AAEA,EAAA,OAAO;AAAA,IACN,UAAA,EAAY,IAAA;AAAA,IACZ,WAAA,EAAa,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,IAAA,CAAK,GAAA,CAAI,MAAA,EAAQ,WAAA,IAAe,oBAAA,CAAqB,WAAA,EAAa,CAAC,CAAC,CAAA;AAAA,IAC7F,gBAAgB,IAAA,CAAK,GAAA,CAAI,GAAG,MAAA,EAAQ,cAAA,IAAkB,qBAAqB,cAAc,CAAA;AAAA,IACzF,mBAAmB,IAAA,CAAK,GAAA;AAAA,MACvB,CAAA;AAAA,MACA,MAAA,EAAQ,qBAAqB,oBAAA,CAAqB;AAAA,KACnD;AAAA,IACA,YAAY,IAAA,CAAK,GAAA,CAAI,GAAG,MAAA,EAAQ,UAAA,IAAc,qBAAqB,UAAU;AAAA,GAC9E;AACD;AAEO,SAAS,eAAA,CAAgB,SAAiB,MAAA,EAA4C;AAC5F,EAAA,MAAM,gBAAA,GACL,OAAO,cAAA,GAAiB,MAAA,CAAO,qBAAqB,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,OAAA,GAAU,CAAC,CAAA;AAE5E,EAAA,OAAO,IAAA,CAAK,GAAA,CAAI,gBAAA,EAAkB,MAAA,CAAO,UAAU,CAAA;AACpD;AASO,SAAS,uBAAuB,MAAA,EAAoD;AAC1F,EAAA,IAAI,OAAO,OAAA,EAAS;AACnB,IAAA,+BAAA,CAAgC,MAAM,CAAA;AACtC,IAAA,OAAO,MAAA,CAAO,OAAA;AAAA,EACf;AACA,EAAA,OAAO,MAAA,CAAO,UAAU,SAAA,GAAY,mBAAA;AACrC;AAOO,SAAS,yBAAA,CACf,MACA,UAAA,EACU;AACV,EAAA,OAAO,SAAS,mBAAA,IAAuB,UAAA;AACxC;AAQO,SAAS,gCAAgC,MAAA,EAAsC;AACrF,EAAA,IAAI,OAAO,OAAA,IAAW,MAAA,CAAO,OAAA,IAAW,MAAA,CAAO,YAAY,SAAA,EAAW;AACrE,IAAA,MAAM,IAAI,KAAA;AAAA,MACT,CAAA,0DAAA,EAA6D,OAAO,OAAO,CAAA,8DAAA;AAAA,KAC5E;AAAA,EACD;AACD;AAEA,eAAsB,wBAA2B,OAAA,EAAiD;AACjG,EAAA,MAAM,MAAA,GAAS,yBAAA,CAA0B,OAAA,CAAQ,MAAA,EAAQ,QAAQ,iBAAiB,CAAA;AAClF,EAAA,MAAM,KAAA,GACL,OAAA,CAAQ,KAAA,KAAU,CAAC,OAAA,KAAY,IAAI,OAAA,CAAQ,CAAC,OAAA,KAAY,UAAA,CAAW,OAAA,EAAS,OAAO,CAAC,CAAA,CAAA;AACrF,EAAA,IAAI,SAAA;AAEJ,EAAA,KAAA,IAAS,OAAA,GAAU,CAAA,EAAG,OAAA,IAAW,MAAA,CAAO,aAAa,OAAA,EAAA,EAAW;AAC/D,IAAA,IAAI;AACH,MAAA,MAAM,SAAS,MAAM,OAAA,CAAQ,OAAA,CAAQ,OAAA,EAAS,OAAO,WAAW,CAAA;AAChE,MAAA,IAAI,OAAA,CAAQ,YAAA,CAAa,MAAM,CAAA,EAAG;AACjC,QAAA,MAAM,QAAQ,SAAA,GAAY,EAAE,SAAS,MAAA,EAAQ,SAAA,EAAW,OAAO,CAAA;AAC/D,QAAA,OAAO,MAAA;AAAA,MACR;AAEA,MAAA,SAAA,GAAY,OAAA,CAAQ,QAAA,CAAS,MAAM,CAAA,IAAK,sCAAA;AACxC,MAAA,MAAM,UAAU,OAAA,CAAQ,eAAA,GACrB,OAAA,CAAQ,eAAA,CAAgB,MAAM,CAAA,GAC9B,mBAAA;AACH,MAAA,MAAM,YACL,yBAAA,CAA0B,OAAA,EAAS,OAAO,UAAU,CAAA,IAAK,UAAU,MAAA,CAAO,WAAA;AAC3E,MAAA,MAAM,WAAA,GAAc,SAAA,GAAY,eAAA,CAAgB,OAAA,EAAS,MAAM,CAAA,GAAI,KAAA,CAAA;AACnE,MAAA,MAAM,OAAA,CAAQ,YAAY,EAAE,OAAA,EAAS,QAAQ,KAAA,EAAO,SAAA,EAAW,SAAA,EAAW,WAAA,EAAa,CAAA;AAEvF,MAAA,IAAI,CAAC,SAAA,EAAW;AACf,QAAA,OAAO,MAAA;AAAA,MACR;AAEA,MAAA,MAAM,KAAA,CAAM,eAAe,CAAC,CAAA;AAAA,IAC7B,SAAS,KAAA,EAAO;AACf,MAAA,SAAA,GAAY,KAAA,YAAiB,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU,OAAO,KAAK,CAAA;AAIjE,MAAA,MAAM,gBAAgB,OAAA,CAAQ,mBAAA,GAC3B,OAAA,CAAQ,mBAAA,CAAoB,KAAK,CAAA,GACjC,mBAAA;AACH,MAAA,MAAM,YACL,yBAAA,CAA0B,aAAA,EAAe,OAAO,UAAU,CAAA,IAAK,UAAU,MAAA,CAAO,WAAA;AACjF,MAAA,MAAM,WAAA,GAAc,SAAA,GAAY,eAAA,CAAgB,OAAA,EAAS,MAAM,CAAA,GAAI,MAAA;AACnE,MAAA,MAAM,OAAA,CAAQ,YAAY,EAAE,OAAA,EAAS,OAAO,SAAA,EAAW,SAAA,EAAW,aAAa,CAAA;AAE/E,MAAA,IAAI,CAAC,SAAA,EAAW;AACf,QAAA,MAAM,KAAA;AAAA,MACP;AAEA,MAAA,MAAM,KAAA,CAAM,eAAe,CAAC,CAAA;AAAA,IAC7B;AAAA,EACD;AAEA,EAAA,MAAM,IAAI,KAAA,CAAM,SAAA,IAAa,yBAAyB,CAAA;AACvD","file":"chunk-FAG2RTPM.js","sourcesContent":["export interface AdapterExecutionContext {\n\ttenantId: string;\n\tspaceId: string;\n\tactionInvocationId: string;\n\tadapterInvocationId: string;\n\tcorrelationId: string;\n\tcausationId?: string;\n\tattempt: number;\n\tmaxAttempts: number;\n\t/** Epoch-millis deadline after which the adapter should abandon the call. */\n\tdeadlineMs?: number;\n\t/** Set by the host when the invocation has been cancelled; adapters should stop work. */\n\tcancelled?: boolean;\n\t/** Non-secret reason the invocation was cancelled. */\n\tcancellationReason?: string;\n\t/**\n\t * AbortSignal the host aborts when the deadline expires or the invocation is\n\t * cancelled. Adapters should propagate this to underlying HTTP/database\n\t * clients so in-flight work is abandoned rather than left dangling.\n\t */\n\tsignal?: AbortSignal;\n}\n\n/**\n * Additive classification of an adapter outcome so the retry layer can\n * distinguish retryable transient failures from permanent rejections,\n * timeouts, and ambiguous results that require manual reconciliation.\n *\n * When `outcome` is absent on an {@link AdapterExecutionResult}, the retry\n * layer treats a non-success result as `transient_failure` for backward\n * compatibility.\n */\nexport type AdapterOutcomeKind =\n\t| \"success\"\n\t| \"transient_failure\"\n\t| \"permanent_failure\"\n\t| \"timeout\"\n\t| \"ambiguous\";\n\n/**\n * Durable, non-secret evidence attached to a classified adapter outcome.\n * Used by the host to record reconciliation evidence when an adapter returns\n * an ambiguous result whose external effect may or may not have been applied.\n */\nexport interface AdapterOutcomeEvidence {\n\tkind: AdapterOutcomeKind;\n\treason?: string;\n\t/** Opaque, non-secret reference to external operation state for reconciliation. */\n\texternalReference?: string;\n\t/** Whether the external effect may have been applied (true for ambiguous/timeout). */\n\teffectMayHaveApplied?: boolean;\n\tobservedAt: Date | string;\n}\n\n/**\n * An adapter handed the work to an external system that will finish it later.\n *\n * Explicit rather than inferred from evidence: a successful adapter call that\n * merely records a reference is not the same as one that has left the outcome\n * in someone else's hands. The host keeps the invocation running and expects a\n * completion carrying this reference through its completion ingress.\n */\nexport interface AcceptedExternalOperation {\n\t/** Opaque, non-secret reference the external system will complete by. */\n\texternalReference: string;\n\t/** When the external system said it expects to finish, if it said. */\n\texpectedBy?: Date | string;\n}\n\nexport interface AdapterExecutionResult {\n\tsuccess: boolean;\n\tcorrelationId?: string;\n\terror?: string;\n\t/** Additive outcome classification. Omitted = infer from `success`. */\n\toutcome?: AdapterOutcomeKind;\n\t/** Durable evidence for ambiguous or timeout outcomes requiring reconciliation. */\n\toutcomeEvidence?: AdapterOutcomeEvidence;\n\t/** Present when a successful call handed the work off to finish elsewhere. */\n\tacceptedExternalOperation?: AcceptedExternalOperation;\n}\n\nexport type AdapterExecutor = (\n\tinput: Record<string, unknown>,\n\tcontext: AdapterExecutionContext,\n) => Promise<AdapterExecutionResult>;\n\nexport interface AdapterRetryPolicy {\n\t/** External calls must explicitly opt into retry by being idempotent. */\n\tidempotent: boolean;\n\t/** Total attempts including the first call. Non-idempotent policies are forced to 1. */\n\tmaxAttempts?: number;\n\t/** First backoff delay in milliseconds. */\n\tinitialDelayMs?: number;\n\t/** Exponential multiplier applied after each failed attempt. */\n\tbackoffMultiplier?: number;\n\t/** Upper bound for any single retry delay in milliseconds. */\n\tmaxDelayMs?: number;\n}\n\nexport interface ResolvedAdapterRetryPolicy {\n\tidempotent: boolean;\n\tmaxAttempts: number;\n\tinitialDelayMs: number;\n\tbackoffMultiplier: number;\n\tmaxDelayMs: number;\n}\n\nexport interface AdapterCircuitBreakerConfig {\n\tmode: \"monitor\" | \"enforce\";\n\tfailureThreshold: number;\n\twindowMs: number;\n\tcooldownMs: number;\n\tminimumSamples?: number;\n}\n\nexport interface AdapterImplementation {\n\tadapterType: string;\n\toperation: string;\n\tvendor: string;\n\t/** Whether this adapter operation can be safely retried by default. */\n\tidempotent: boolean;\n\tretryPolicy?: AdapterRetryPolicy;\n\t/** Defaults to monitor-only; enforce mode must be explicitly configured. */\n\tcircuitBreaker?: AdapterCircuitBreakerConfig;\n\texecute: AdapterExecutor;\n}\n\nexport interface AdapterAttempt<T> {\n\tattempt: number;\n\tresult?: T;\n\terror?: string;\n\twillRetry: boolean;\n\tnextDelayMs?: number;\n}\n\nexport interface ExecuteWithRetryOptions<T> {\n\tpolicy?: AdapterRetryPolicy;\n\tdefaultIdempotent: boolean;\n\texecute: (attempt: number, maxAttempts: number) => Promise<T>;\n\tisSuccessful: (result: T) => boolean;\n\tgetError: (result: T) => string | undefined;\n\t/**\n\t * Optional outcome classifier. When provided, the retry layer retries only\n\t * `transient_failure` outcomes (and only when the policy is idempotent).\n\t * `permanent_failure`, `timeout`, and `ambiguous` outcomes are never retried.\n\t * When omitted, all non-success results are treated as transient (backward compatible).\n\t */\n\tclassifyOutcome?: (result: T) => AdapterOutcomeKind;\n\t/**\n\t * Optional classifier for errors thrown by the execute callback (not returned\n\t * as results). When provided, the retry layer retries only `transient_failure`\n\t * classifications. When omitted, thrown errors are never retried — the caller\n\t * must explicitly opt into retrying a thrown failure by classifying it.\n\t */\n\tclassifyThrownError?: (error: unknown) => AdapterOutcomeKind;\n\tsleep?: (delayMs: number) => Promise<void>;\n\tonAttempt?: (attempt: AdapterAttempt<T>) => Promise<void> | void;\n}\n\nfunction adapterKey(adapterType: string, operation: string): string {\n\treturn `${adapterType}:${operation}`;\n}\n\nexport class MissingAdapterRegistrationError extends Error {\n\tconstructor(adapterType: string, operation: string) {\n\t\tsuper(`No adapter registered for adapterType \"${adapterType}\" and operation \"${operation}\"`);\n\t\tthis.name = \"MissingAdapterRegistrationError\";\n\t}\n}\n\nexport class AdapterRegistry {\n\tprivate readonly adapters = new Map<string, AdapterImplementation>();\n\n\tregister(adapter: AdapterImplementation): void {\n\t\tconst key = adapterKey(adapter.adapterType, adapter.operation);\n\t\tif (this.adapters.has(key)) {\n\t\t\tthrow new Error(\n\t\t\t\t`Adapter already registered for adapterType \"${adapter.adapterType}\" and operation \"${adapter.operation}\"`,\n\t\t\t);\n\t\t}\n\n\t\tthis.adapters.set(key, adapter);\n\t}\n\n\tresolve(adapterType: string, operation: string): AdapterImplementation | undefined {\n\t\treturn this.adapters.get(adapterKey(adapterType, operation));\n\t}\n\n\trequire(adapterType: string, operation: string): AdapterImplementation {\n\t\tconst adapter = this.resolve(adapterType, operation);\n\t\tif (!adapter) {\n\t\t\tthrow new MissingAdapterRegistrationError(adapterType, operation);\n\t\t}\n\n\t\treturn adapter;\n\t}\n}\n\nconst DEFAULT_RETRY_POLICY: ResolvedAdapterRetryPolicy = {\n\tidempotent: true,\n\tmaxAttempts: 3,\n\tinitialDelayMs: 100,\n\tbackoffMultiplier: 2,\n\tmaxDelayMs: 1_000,\n};\n\nconst NO_RETRY_POLICY: ResolvedAdapterRetryPolicy = {\n\tidempotent: false,\n\tmaxAttempts: 1,\n\tinitialDelayMs: 0,\n\tbackoffMultiplier: 1,\n\tmaxDelayMs: 0,\n};\n\nexport function resolveAdapterRetryPolicy(\n\tpolicy: AdapterRetryPolicy | undefined,\n\tdefaultIdempotent: boolean,\n): ResolvedAdapterRetryPolicy {\n\tconst idempotent = policy?.idempotent ?? defaultIdempotent;\n\n\tif (!idempotent) {\n\t\treturn NO_RETRY_POLICY;\n\t}\n\n\treturn {\n\t\tidempotent: true,\n\t\tmaxAttempts: Math.max(1, Math.min(policy?.maxAttempts ?? DEFAULT_RETRY_POLICY.maxAttempts, 5)),\n\t\tinitialDelayMs: Math.max(0, policy?.initialDelayMs ?? DEFAULT_RETRY_POLICY.initialDelayMs),\n\t\tbackoffMultiplier: Math.max(\n\t\t\t1,\n\t\t\tpolicy?.backoffMultiplier ?? DEFAULT_RETRY_POLICY.backoffMultiplier,\n\t\t),\n\t\tmaxDelayMs: Math.max(0, policy?.maxDelayMs ?? DEFAULT_RETRY_POLICY.maxDelayMs),\n\t};\n}\n\nexport function getRetryDelayMs(attempt: number, policy: ResolvedAdapterRetryPolicy): number {\n\tconst exponentialDelay =\n\t\tpolicy.initialDelayMs * policy.backoffMultiplier ** Math.max(0, attempt - 1);\n\n\treturn Math.min(exponentialDelay, policy.maxDelayMs);\n}\n\n/**\n * Classify an {@link AdapterExecutionResult} into an {@link AdapterOutcomeKind}.\n * When `outcome` is explicitly set, it is returned directly, after rejecting a\n * contradictory result where `success` is true but the outcome is non-success.\n * Otherwise a successful result maps to `success` and a failed result maps to\n * `transient_failure` (the historical default).\n */\nexport function classifyAdapterOutcome(result: AdapterExecutionResult): AdapterOutcomeKind {\n\tif (result.outcome) {\n\t\tassertAdapterOutcomeConsistency(result);\n\t\treturn result.outcome;\n\t}\n\treturn result.success ? \"success\" : \"transient_failure\";\n}\n\n/**\n * Determine whether an outcome kind is retryable. Only `transient_failure`\n * is retryable, and only when the adapter policy is idempotent. Permanent\n * failures, timeouts, and ambiguous outcomes are never retried.\n */\nexport function shouldRetryAdapterOutcome(\n\tkind: AdapterOutcomeKind,\n\tidempotent: boolean,\n): boolean {\n\treturn kind === \"transient_failure\" && idempotent;\n}\n\n/**\n * Reject a contradictory adapter result where `success` is true but the\n * explicit `outcome` is a non-success kind. A successful result claiming an\n * ambiguous, permanent, timeout, or transient outcome is a programming\n * error — the adapter cannot have both succeeded and require reconciliation.\n */\nexport function assertAdapterOutcomeConsistency(result: AdapterExecutionResult): void {\n\tif (result.success && result.outcome && result.outcome !== \"success\") {\n\t\tthrow new Error(\n\t\t\t`Adapter returned success=true with contradictory outcome \"${result.outcome}\"; a successful result must not declare a non-success outcome.`,\n\t\t);\n\t}\n}\n\nexport async function executeWithAdapterRetry<T>(options: ExecuteWithRetryOptions<T>): Promise<T> {\n\tconst policy = resolveAdapterRetryPolicy(options.policy, options.defaultIdempotent);\n\tconst sleep =\n\t\toptions.sleep ?? ((delayMs) => new Promise((resolve) => setTimeout(resolve, delayMs)));\n\tlet lastError: string | undefined;\n\n\tfor (let attempt = 1; attempt <= policy.maxAttempts; attempt++) {\n\t\ttry {\n\t\t\tconst result = await options.execute(attempt, policy.maxAttempts);\n\t\t\tif (options.isSuccessful(result)) {\n\t\t\t\tawait options.onAttempt?.({ attempt, result, willRetry: false });\n\t\t\t\treturn result;\n\t\t\t}\n\n\t\t\tlastError = options.getError(result) ?? \"Adapter returned unsuccessful result\";\n\t\t\tconst outcome = options.classifyOutcome\n\t\t\t\t? options.classifyOutcome(result)\n\t\t\t\t: \"transient_failure\" as const;\n\t\t\tconst willRetry =\n\t\t\t\tshouldRetryAdapterOutcome(outcome, policy.idempotent) && attempt < policy.maxAttempts;\n\t\t\tconst nextDelayMs = willRetry ? getRetryDelayMs(attempt, policy) : undefined;\n\t\t\tawait options.onAttempt?.({ attempt, result, error: lastError, willRetry, nextDelayMs });\n\n\t\t\tif (!willRetry) {\n\t\t\t\treturn result;\n\t\t\t}\n\n\t\t\tawait sleep(nextDelayMs ?? 0);\n\t\t} catch (error) {\n\t\t\tlastError = error instanceof Error ? error.message : String(error);\n\t\t\t// Preserve the pre-classification contract for direct callers. The\n\t\t\t// governed Host supplies a classifier and therefore remains fail-closed\n\t\t\t// for ambiguous, timeout, and permanent failures.\n\t\t\tconst thrownOutcome = options.classifyThrownError\n\t\t\t\t? options.classifyThrownError(error)\n\t\t\t\t: \"transient_failure\" as const;\n\t\t\tconst willRetry =\n\t\t\t\tshouldRetryAdapterOutcome(thrownOutcome, policy.idempotent) && attempt < policy.maxAttempts;\n\t\t\tconst nextDelayMs = willRetry ? getRetryDelayMs(attempt, policy) : undefined;\n\t\t\tawait options.onAttempt?.({ attempt, error: lastError, willRetry, nextDelayMs });\n\n\t\t\tif (!willRetry) {\n\t\t\t\tthrow error;\n\t\t\t}\n\n\t\t\tawait sleep(nextDelayMs ?? 0);\n\t\t}\n\t}\n\n\tthrow new Error(lastError ?? \"Adapter retry exhausted\");\n}\n"]}
@@ -1,6 +1,6 @@
1
1
  import { assertPortableJsonSchema } from './chunk-ZAEVQSB5.js';
2
2
  import { viewContractKey } from './chunk-JG35DT2G.js';
3
- import { createEventContractRegistry } from './chunk-NHGBTPPE.js';
3
+ import { createEventContractRegistry } from './chunk-B5DOGDPG.js';
4
4
 
5
5
  // modules/index.ts
6
6
  function getModuleDependencyNamespace(dependency) {
@@ -175,7 +175,7 @@ function validateManifest(module, context = {}) {
175
175
  }
176
176
  }
177
177
  for (const port of module.capability.requirements?.ports ?? []) {
178
- if (!/^[a-z][a-z0-9-]*$/.test(port.name)) throw new Error(`Module "${module.namespace}" capability has invalid port requirement "${port.name}".`);
178
+ if (!/^[a-z][a-z0-9-]*(?:\.[a-z0-9-]+)*$/.test(port.name)) throw new Error(`Module "${module.namespace}" capability has invalid port requirement "${port.name}".`);
179
179
  }
180
180
  validateCapabilityWorkflows(module, context);
181
181
  }
@@ -183,6 +183,8 @@ function validateManifest(module, context = {}) {
183
183
  for (const action of module.actions ?? []) {
184
184
  if (action.execution?.idempotency === "required" && !action.idempotent) throw new Error(`Action "${action.actionId}" requires idempotency but is not declared idempotent.`);
185
185
  if (action.execution?.connectivity === "offline-capturable" && action.execution.idempotency === "prohibited") throw new Error(`Offline action "${action.actionId}" cannot prohibit idempotency.`);
186
+ if (action.execution?.completionDeadlineMs !== void 0 && !(typeof action.execution.completionDeadlineMs === "number" && action.execution.completionDeadlineMs > 0)) throw new Error(`Action "${action.actionId}" completionDeadlineMs must be a positive number of milliseconds.`);
187
+ if (action.execution?.completion === "immediate" && action.execution.completionDeadlineMs !== void 0) throw new Error(`Immediate action "${action.actionId}" cannot declare a completion deadline; nothing external completes it.`);
186
188
  }
187
189
  for (const view of module.views ?? []) if (view.usage?.collection?.filterSchema) assertPortableJsonSchema(view.usage.collection.filterSchema, `View "${view.name}" filter schema`);
188
190
  for (const dependency of dependencies) {
@@ -374,5 +376,5 @@ function registerFabricModule(module) {
374
376
  }
375
377
 
376
378
  export { createModuleRegistry, getEventTypeName, getModuleDependencyNamespace, getObjectTypeName, registerFabricModule, registerFabricModules, validateAndOrderFabricModules, validateModuleNamespace };
377
- //# sourceMappingURL=chunk-63MYMAEX.js.map
378
- //# sourceMappingURL=chunk-63MYMAEX.js.map
379
+ //# sourceMappingURL=chunk-GRBZYDEV.js.map
380
+ //# sourceMappingURL=chunk-GRBZYDEV.js.map