arkgate 2.10.0 → 2.11.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 (42) hide show
  1. package/CHANGELOG.md +43 -0
  2. package/README.md +6 -2
  3. package/SECURITY.md +3 -4
  4. package/bin/ark-check.mjs +41 -16
  5. package/bin/ark-mcp.mjs +54 -10
  6. package/bin/ark.mjs +35 -5
  7. package/bin/lib/agent-gates.mjs +9 -5
  8. package/bin/lib/architecture-scan.mjs +4 -1
  9. package/bin/lib/baseline-key.mjs +17 -0
  10. package/bin/lib/config-warnings.mjs +22 -0
  11. package/bin/lib/core-layers.mjs +7 -0
  12. package/bin/lib/core-ratchet.mjs +3 -7
  13. package/bin/lib/doctor-plan.mjs +29 -5
  14. package/bin/lib/safety-diagnostics.mjs +263 -0
  15. package/bin/lib/scan-files.mjs +51 -6
  16. package/bin/lib/violations.mjs +3 -3
  17. package/dist/index.cjs +103 -8
  18. package/dist/index.cjs.map +1 -1
  19. package/dist/index.d.cts +5 -3
  20. package/dist/index.d.ts +5 -3
  21. package/dist/index.js +103 -8
  22. package/dist/index.js.map +1 -1
  23. package/dist/nestjs/index.cjs +18 -5
  24. package/dist/nestjs/index.cjs.map +1 -1
  25. package/dist/nestjs/index.d.cts +1 -1
  26. package/dist/nestjs/index.d.ts +1 -1
  27. package/dist/nestjs/index.js +18 -5
  28. package/dist/nestjs/index.js.map +1 -1
  29. package/dist/runtime/index.cjs +103 -8
  30. package/dist/runtime/index.cjs.map +1 -1
  31. package/dist/runtime/index.d.cts +1 -1
  32. package/dist/runtime/index.d.ts +1 -1
  33. package/dist/runtime/index.js +103 -8
  34. package/dist/runtime/index.js.map +1 -1
  35. package/dist/{types-D6Q8WHes.d.cts → types-BZ17b9i5.d.cts} +5 -1
  36. package/dist/{types-D6Q8WHes.d.ts → types-BZ17b9i5.d.ts} +5 -1
  37. package/docs/agent-guide.md +1 -1
  38. package/docs/ai-gates.md +20 -2
  39. package/docs/package-surface.md +2 -2
  40. package/docs/production-hardening.md +5 -0
  41. package/package.json +5 -2
  42. package/server.json +2 -2
package/dist/index.d.cts CHANGED
@@ -1,8 +1,8 @@
1
- import { I as IntentRegistry, a as IntentName, D as DefineIntentOptions, b as IntentCreator, P as PolicyViolation, c as PolicySeverity, d as PolicyEnforcementMode, e as Policy, f as CreateArchitectureProfileOptions, g as ArchitectureProfile, h as ArkCheckConfig, i as CreateArchitectureProfileFromArkConfigOptions, j as CreateElevenLayerArkConfigOptions, k as DependencyGraph, G as GraphEdge, l as IntentRelationship, m as AuditStore, n as AuditRecord, o as AuditQuery, p as CreateAuditTrailOptions, q as AuditTrail, E as EventContractRegistry, r as EventContract, s as DomainEvent, t as EventContractValidationResult, O as OutboxStore, u as OutboxRecord, v as OutboxStatus, w as EventBusOptions, x as EventBus, y as CreateObservabilityReporterOptions, z as ObservabilityReporter, M as MetadataRegistry, R as ReadModelStore, B as CreateProjectionRegistryOptions, F as ProjectionRegistry, H as PolicyEngine, J as ArkManifest, W as WorkflowStore, S as SagaContext, K as WorkflowSnapshot, L as SagaDefinition, N as CreateWorkflowEngineOptions, Q as SagaInstance, T as WorkflowEngine, C as CreateArkKernelOptions, A as ArkKernel, U as ArkKernelConfig, V as CreateArkKernelFromConfigOptions, X as TraceRecordType, Y as TraceRecord, Z as ObservabilityDriftReport } from './types-D6Q8WHes.cjs';
2
- export { _ as ArchitectureLayer, $ as ArchitectureLayerConfig, a0 as ArchitectureRule, a1 as ArkManifestArchitecture, a2 as ArkManifestData, a3 as ArkManifestEntityLink, a4 as ArkManifestGraph, a5 as ArkManifestIntent, a6 as ArkManifestPolicy, a7 as ArkManifestProjection, a8 as AuditRecordInput, a9 as AuditRecordType, aa as CorrelationId, ab as EntityMeta, ac as EventContractIssue, ad as EventHandler, ae as EventInterceptionInfo, af as EventInterceptor, ag as EventInterceptorContext, ah as EventMetadata, ai as EventPayloadPatch, aj as EventPayloadSchema, ak as EventPublisher, al as EventSchemaField, am as EventSchemaFieldType, an as FieldMeta, ao as GraphNode, ap as IntentRelationshipKind, aq as ObservabilityFlow, ar as ObservedLayerFlowMode, as as PolicyEvaluationResult, at as ProjectionCheckpoint, au as ProjectionDefinition, av as PublishedEventRecord, aw as RetryPolicy, ax as SagaStatus, ay as SagaStep, az as TraceSink, aA as Unsubscribe, aB as WorkflowDefinition, aC as WorkflowStatus, aD as WorkflowStep } from './types-D6Q8WHes.cjs';
1
+ import { I as IntentRegistry, a as IntentName, D as DefineIntentOptions, b as IntentCreator, P as PolicyViolation, c as PolicySeverity, d as PolicyEnforcementMode, e as Policy, f as CreateArchitectureProfileOptions, g as ArchitectureProfile, h as ArkCheckConfig, i as CreateArchitectureProfileFromArkConfigOptions, j as CreateElevenLayerArkConfigOptions, k as DependencyGraph, G as GraphEdge, l as IntentRelationship, m as AuditStore, n as AuditRecord, o as AuditQuery, p as CreateAuditTrailOptions, q as AuditTrail, E as EventContractRegistry, r as EventContract, s as DomainEvent, t as EventContractValidationResult, O as OutboxStore, u as OutboxRecord, v as OutboxStatus, w as EventBusOptions, x as EventBus, y as CreateObservabilityReporterOptions, z as ObservabilityReporter, M as MetadataRegistry, R as ReadModelStore, B as CreateProjectionRegistryOptions, F as ProjectionRegistry, H as PolicyEngine, J as ArkManifest, W as WorkflowStore, S as SagaContext, K as WorkflowSnapshot, L as SagaDefinition, N as CreateWorkflowEngineOptions, Q as SagaInstance, T as WorkflowEngine, C as CreateArkKernelOptions, A as ArkKernel, U as ArkKernelConfig, V as CreateArkKernelFromConfigOptions, X as TraceRecordType, Y as TraceRecord, Z as ObservabilityDriftReport } from './types-BZ17b9i5.cjs';
2
+ export { _ as ArchitectureLayer, $ as ArchitectureLayerConfig, a0 as ArchitectureRule, a1 as ArkManifestArchitecture, a2 as ArkManifestData, a3 as ArkManifestEntityLink, a4 as ArkManifestGraph, a5 as ArkManifestIntent, a6 as ArkManifestPolicy, a7 as ArkManifestProjection, a8 as AuditRecordInput, a9 as AuditRecordType, aa as CorrelationId, ab as EntityMeta, ac as EventContractIssue, ad as EventHandler, ae as EventInterceptionInfo, af as EventInterceptor, ag as EventInterceptorContext, ah as EventMetadata, ai as EventPayloadPatch, aj as EventPayloadSchema, ak as EventPublisher, al as EventSchemaField, am as EventSchemaFieldType, an as FieldMeta, ao as GraphNode, ap as IntentRelationshipKind, aq as ObservabilityFlow, ar as ObservedLayerFlowMode, as as PolicyEvaluationResult, at as ProjectionCheckpoint, au as ProjectionDefinition, av as PublishedEventRecord, aw as RetryPolicy, ax as SagaStatus, ay as SagaStep, az as TraceSink, aA as Unsubscribe, aB as WorkflowDefinition, aC as WorkflowStatus, aD as WorkflowStep } from './types-BZ17b9i5.cjs';
3
3
 
4
4
  /** ArkGate library version — single source of truth. */
5
- declare const version = "2.10.0";
5
+ declare const version = "2.11.0";
6
6
 
7
7
  /**
8
8
  * defineIntent
@@ -603,6 +603,8 @@ interface AICodeGateOptions<Context = AICodeGateContext> {
603
603
  name: string;
604
604
  patterns?: string[];
605
605
  }>;
606
+ /** Explicit file-level escape hatch for reviewed non-literal dynamic imports. */
607
+ allowNonLiteralDynamicImport?: (filePath?: string) => boolean;
606
608
  }
607
609
  declare function createAICodeGate<Context = AICodeGateContext>(options?: AICodeGateOptions<Context>): AICodeGate<Context>;
608
610
 
package/dist/index.d.ts CHANGED
@@ -1,8 +1,8 @@
1
- import { I as IntentRegistry, a as IntentName, D as DefineIntentOptions, b as IntentCreator, P as PolicyViolation, c as PolicySeverity, d as PolicyEnforcementMode, e as Policy, f as CreateArchitectureProfileOptions, g as ArchitectureProfile, h as ArkCheckConfig, i as CreateArchitectureProfileFromArkConfigOptions, j as CreateElevenLayerArkConfigOptions, k as DependencyGraph, G as GraphEdge, l as IntentRelationship, m as AuditStore, n as AuditRecord, o as AuditQuery, p as CreateAuditTrailOptions, q as AuditTrail, E as EventContractRegistry, r as EventContract, s as DomainEvent, t as EventContractValidationResult, O as OutboxStore, u as OutboxRecord, v as OutboxStatus, w as EventBusOptions, x as EventBus, y as CreateObservabilityReporterOptions, z as ObservabilityReporter, M as MetadataRegistry, R as ReadModelStore, B as CreateProjectionRegistryOptions, F as ProjectionRegistry, H as PolicyEngine, J as ArkManifest, W as WorkflowStore, S as SagaContext, K as WorkflowSnapshot, L as SagaDefinition, N as CreateWorkflowEngineOptions, Q as SagaInstance, T as WorkflowEngine, C as CreateArkKernelOptions, A as ArkKernel, U as ArkKernelConfig, V as CreateArkKernelFromConfigOptions, X as TraceRecordType, Y as TraceRecord, Z as ObservabilityDriftReport } from './types-D6Q8WHes.js';
2
- export { _ as ArchitectureLayer, $ as ArchitectureLayerConfig, a0 as ArchitectureRule, a1 as ArkManifestArchitecture, a2 as ArkManifestData, a3 as ArkManifestEntityLink, a4 as ArkManifestGraph, a5 as ArkManifestIntent, a6 as ArkManifestPolicy, a7 as ArkManifestProjection, a8 as AuditRecordInput, a9 as AuditRecordType, aa as CorrelationId, ab as EntityMeta, ac as EventContractIssue, ad as EventHandler, ae as EventInterceptionInfo, af as EventInterceptor, ag as EventInterceptorContext, ah as EventMetadata, ai as EventPayloadPatch, aj as EventPayloadSchema, ak as EventPublisher, al as EventSchemaField, am as EventSchemaFieldType, an as FieldMeta, ao as GraphNode, ap as IntentRelationshipKind, aq as ObservabilityFlow, ar as ObservedLayerFlowMode, as as PolicyEvaluationResult, at as ProjectionCheckpoint, au as ProjectionDefinition, av as PublishedEventRecord, aw as RetryPolicy, ax as SagaStatus, ay as SagaStep, az as TraceSink, aA as Unsubscribe, aB as WorkflowDefinition, aC as WorkflowStatus, aD as WorkflowStep } from './types-D6Q8WHes.js';
1
+ import { I as IntentRegistry, a as IntentName, D as DefineIntentOptions, b as IntentCreator, P as PolicyViolation, c as PolicySeverity, d as PolicyEnforcementMode, e as Policy, f as CreateArchitectureProfileOptions, g as ArchitectureProfile, h as ArkCheckConfig, i as CreateArchitectureProfileFromArkConfigOptions, j as CreateElevenLayerArkConfigOptions, k as DependencyGraph, G as GraphEdge, l as IntentRelationship, m as AuditStore, n as AuditRecord, o as AuditQuery, p as CreateAuditTrailOptions, q as AuditTrail, E as EventContractRegistry, r as EventContract, s as DomainEvent, t as EventContractValidationResult, O as OutboxStore, u as OutboxRecord, v as OutboxStatus, w as EventBusOptions, x as EventBus, y as CreateObservabilityReporterOptions, z as ObservabilityReporter, M as MetadataRegistry, R as ReadModelStore, B as CreateProjectionRegistryOptions, F as ProjectionRegistry, H as PolicyEngine, J as ArkManifest, W as WorkflowStore, S as SagaContext, K as WorkflowSnapshot, L as SagaDefinition, N as CreateWorkflowEngineOptions, Q as SagaInstance, T as WorkflowEngine, C as CreateArkKernelOptions, A as ArkKernel, U as ArkKernelConfig, V as CreateArkKernelFromConfigOptions, X as TraceRecordType, Y as TraceRecord, Z as ObservabilityDriftReport } from './types-BZ17b9i5.js';
2
+ export { _ as ArchitectureLayer, $ as ArchitectureLayerConfig, a0 as ArchitectureRule, a1 as ArkManifestArchitecture, a2 as ArkManifestData, a3 as ArkManifestEntityLink, a4 as ArkManifestGraph, a5 as ArkManifestIntent, a6 as ArkManifestPolicy, a7 as ArkManifestProjection, a8 as AuditRecordInput, a9 as AuditRecordType, aa as CorrelationId, ab as EntityMeta, ac as EventContractIssue, ad as EventHandler, ae as EventInterceptionInfo, af as EventInterceptor, ag as EventInterceptorContext, ah as EventMetadata, ai as EventPayloadPatch, aj as EventPayloadSchema, ak as EventPublisher, al as EventSchemaField, am as EventSchemaFieldType, an as FieldMeta, ao as GraphNode, ap as IntentRelationshipKind, aq as ObservabilityFlow, ar as ObservedLayerFlowMode, as as PolicyEvaluationResult, at as ProjectionCheckpoint, au as ProjectionDefinition, av as PublishedEventRecord, aw as RetryPolicy, ax as SagaStatus, ay as SagaStep, az as TraceSink, aA as Unsubscribe, aB as WorkflowDefinition, aC as WorkflowStatus, aD as WorkflowStep } from './types-BZ17b9i5.js';
3
3
 
4
4
  /** ArkGate library version — single source of truth. */
5
- declare const version = "2.10.0";
5
+ declare const version = "2.11.0";
6
6
 
7
7
  /**
8
8
  * defineIntent
@@ -603,6 +603,8 @@ interface AICodeGateOptions<Context = AICodeGateContext> {
603
603
  name: string;
604
604
  patterns?: string[];
605
605
  }>;
606
+ /** Explicit file-level escape hatch for reviewed non-literal dynamic imports. */
607
+ allowNonLiteralDynamicImport?: (filePath?: string) => boolean;
606
608
  }
607
609
  declare function createAICodeGate<Context = AICodeGateContext>(options?: AICodeGateOptions<Context>): AICodeGate<Context>;
608
610
 
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  // src/version.ts
2
- var version = "2.10.0";
2
+ var version = "2.11.0";
3
3
 
4
4
  // src/kernel/intent/IntentRegistry.ts
5
5
  var IntentRegistry = class {
@@ -2181,6 +2181,75 @@ function extractModuleSpecifiers(source) {
2181
2181
  }
2182
2182
  return matches.sort((a, b) => a.index - b.index);
2183
2183
  }
2184
+ function extractModuleSpecifiersAst(ts, source) {
2185
+ const sourceFile = ts.createSourceFile("generated.ts", source, ts.ScriptTarget.Latest, true);
2186
+ const matches = [];
2187
+ const push = (node, value, kind, typeOnly = false) => {
2188
+ matches.push({
2189
+ value,
2190
+ index: node.getStart(sourceFile),
2191
+ kind,
2192
+ typeOnly
2193
+ });
2194
+ };
2195
+ const visit = (node) => {
2196
+ if (ts.isImportDeclaration(node) && ts.isStringLiteralLike(node.moduleSpecifier)) {
2197
+ const clause = node.importClause;
2198
+ const namedBindings = clause?.namedBindings;
2199
+ const specifiersOnly = clause && !clause.name && namedBindings && ts.isNamedImports(namedBindings) && namedBindings.elements.length > 0 && namedBindings.elements.every((element) => element.isTypeOnly === true);
2200
+ push(
2201
+ node.moduleSpecifier,
2202
+ node.moduleSpecifier.text,
2203
+ "import",
2204
+ Boolean(clause?.isTypeOnly || specifiersOnly)
2205
+ );
2206
+ } else if (ts.isExportDeclaration(node) && ts.isStringLiteralLike(node.moduleSpecifier)) {
2207
+ const clause = node.exportClause;
2208
+ const specifiersOnly = clause && ts.isNamedExports(clause) && clause.elements.length > 0 && clause.elements.every((element) => element.isTypeOnly === true);
2209
+ push(
2210
+ node.moduleSpecifier,
2211
+ node.moduleSpecifier.text,
2212
+ "export",
2213
+ Boolean(node.isTypeOnly || specifiersOnly)
2214
+ );
2215
+ } else if (ts.isCallExpression(node) && node.arguments.length === 1) {
2216
+ const argument = node.arguments[0];
2217
+ const value = tsStringLiteralText(ts, argument);
2218
+ if (value !== void 0 && node.expression.kind === ts.SyntaxKind.ImportKeyword) {
2219
+ push(argument, value, "dynamic-import");
2220
+ } else if (value !== void 0 && ts.isIdentifier(node.expression) && node.expression.text === "require") {
2221
+ push(argument, value, "require");
2222
+ }
2223
+ }
2224
+ ts.forEachChild(node, visit);
2225
+ };
2226
+ visit(sourceFile);
2227
+ return matches.sort((a, b) => a.index - b.index);
2228
+ }
2229
+ function nonLiteralDynamicImportLines(ts, source) {
2230
+ const sourceFile = ts.createSourceFile("generated.ts", source, ts.ScriptTarget.Latest, true);
2231
+ const lines = [];
2232
+ const visit = (node) => {
2233
+ if (ts.isCallExpression(node) && node.expression.kind === ts.SyntaxKind.ImportKeyword && (!node.arguments[0] || !ts.isStringLiteralLike(node.arguments[0]))) {
2234
+ lines.push(sourceFile.getLineAndCharacterOfPosition(node.getStart(sourceFile)).line + 1);
2235
+ }
2236
+ ts.forEachChild(node, visit);
2237
+ };
2238
+ visit(sourceFile);
2239
+ return lines;
2240
+ }
2241
+ function extractQuotedStringsAst(ts, source) {
2242
+ const sourceFile = ts.createSourceFile("generated.ts", source, ts.ScriptTarget.Latest, true);
2243
+ const matches = [];
2244
+ const visit = (node) => {
2245
+ if (ts.isStringLiteralLike(node)) {
2246
+ matches.push({ value: node.text, index: node.getStart(sourceFile) });
2247
+ }
2248
+ ts.forEachChild(node, visit);
2249
+ };
2250
+ visit(sourceFile);
2251
+ return matches;
2252
+ }
2184
2253
  function looksLikeIntentName(s) {
2185
2254
  return /^(Domain|Application|Adapter|Workflow|Job|Presentation|Reporting|Metadata|Security|Audit|Observability|Kernel)\.[A-Za-z0-9_.]+$/.test(s);
2186
2255
  }
@@ -2375,6 +2444,19 @@ function createAICodeGate(options = {}) {
2375
2444
  const gateContext = context;
2376
2445
  const filePath = gateContext?.filePath;
2377
2446
  const contextLayer = gateContext?.layer;
2447
+ const moduleSpecifiers = options.typescript ? extractModuleSpecifiersAst(options.typescript, source) : extractModuleSpecifiers(source);
2448
+ const quotedStrings = options.typescript ? extractQuotedStringsAst(options.typescript, source) : extractQuotedStrings(source);
2449
+ if (options.typescript && !options.allowNonLiteralDynamicImport?.(filePath)) {
2450
+ for (const line of nonLiteralDynamicImportLines(options.typescript, source)) {
2451
+ violations.push(
2452
+ violation(
2453
+ "DYNAMIC_IMPORT_NOT_ALLOWLISTED",
2454
+ "Non-literal dynamic import cannot be resolved statically; add the reviewed file to dynamicImportAllowlist.",
2455
+ { line, filePath }
2456
+ )
2457
+ );
2458
+ }
2459
+ }
2378
2460
  const exemptFromInfraHeuristics = contextLayer !== void 0 && (explicitInfraLayers.has(contextLayer) || layerHasInfrastructureRole(contextLayer));
2379
2461
  const infraLayerEscapeHatch = contextLayer !== void 0 ? ` If "${contextLayer}" is an infrastructure layer, mark it in ark.config.json with "mayImportInfrastructure": true (or name it with an infra token like Adapters/Persistence/Repository).` : "";
2380
2462
  for (const pat of userForbidden) {
@@ -2400,7 +2482,7 @@ function createAICodeGate(options = {}) {
2400
2482
  );
2401
2483
  }
2402
2484
  }
2403
- for (const specifier of extractModuleSpecifiers(source)) {
2485
+ for (const specifier of moduleSpecifiers) {
2404
2486
  const targetHit = options.resolveImportTarget?.(specifier.value, filePath) ?? (options.resolveImportLayer ? { layer: options.resolveImportLayer(specifier.value, filePath) } : void 0);
2405
2487
  const sourceHit = typeof filePath === "string" ? options.resolveImportTarget?.(filePath) ?? (options.resolveImportLayer ? { layer: contextLayer, relPath: void 0 } : void 0) : void 0;
2406
2488
  const targetLayer = targetHit?.layer;
@@ -2491,7 +2573,7 @@ function createAICodeGate(options = {}) {
2491
2573
  }
2492
2574
  }
2493
2575
  if (enforceAllowlist && intentNames.size > 0) {
2494
- for (const literal of extractQuotedStrings(source)) {
2576
+ for (const literal of quotedStrings) {
2495
2577
  if (looksLikeIntentName(literal.value) && !intentNames.has(literal.value)) {
2496
2578
  violations.push(
2497
2579
  violation(
@@ -2509,7 +2591,7 @@ function createAICodeGate(options = {}) {
2509
2591
  }
2510
2592
  }
2511
2593
  if (options.architectureProfile && contextLayer) {
2512
- for (const literal of extractQuotedStrings(source)) {
2594
+ for (const literal of quotedStrings) {
2513
2595
  if (!looksLikeIntentName(literal.value)) continue;
2514
2596
  const targetLayer = options.architectureProfile.resolveLayer(literal.value);
2515
2597
  if (!targetLayer) continue;
@@ -2785,15 +2867,18 @@ function sleep(ms) {
2785
2867
  });
2786
2868
  }
2787
2869
  async function withTimeout(operation, timeoutMs, stepName) {
2788
- if (timeoutMs === void 0) return operation;
2870
+ const controller = new AbortController();
2871
+ if (timeoutMs === void 0) return operation(controller.signal);
2789
2872
  let timeout;
2790
2873
  const timeoutPromise = new Promise((_, reject) => {
2791
2874
  timeout = setTimeout(() => {
2792
- reject(new Error(`Workflow step "${stepName}" timed out after ${timeoutMs}ms.`));
2875
+ const error = new Error(`Workflow step "${stepName}" timed out after ${timeoutMs}ms.`);
2876
+ controller.abort(error);
2877
+ reject(error);
2793
2878
  }, timeoutMs);
2794
2879
  });
2795
2880
  try {
2796
- return await Promise.race([operation, timeoutPromise]);
2881
+ return await Promise.race([operation(controller.signal), timeoutPromise]);
2797
2882
  } finally {
2798
2883
  if (timeout) clearTimeout(timeout);
2799
2884
  }
@@ -2828,6 +2913,15 @@ var WorkflowEngineImpl = class {
2828
2913
  if (this.definitions.has(definition.name)) {
2829
2914
  throw new Error(`Workflow "${definition.name}" is already registered.`);
2830
2915
  }
2916
+ const names = /* @__PURE__ */ new Set();
2917
+ for (const step of definition.steps) {
2918
+ if (names.has(step.name)) {
2919
+ throw new Error(
2920
+ `Workflow "${definition.name}" has duplicate step name "${step.name}".`
2921
+ );
2922
+ }
2923
+ names.add(step.name);
2924
+ }
2831
2925
  this.definitions.set(definition.name, definition);
2832
2926
  if (definition.startOn) {
2833
2927
  const trigger = definition.startOn;
@@ -2868,6 +2962,7 @@ var WorkflowEngineImpl = class {
2868
2962
  } catch (err) {
2869
2963
  await this.compensate(snapshot, definition.steps, err);
2870
2964
  snapshot.status = "failed";
2965
+ snapshot.currentStep = void 0;
2871
2966
  snapshot.error = errorMessage(err);
2872
2967
  snapshot.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
2873
2968
  await this.store.save(snapshot);
@@ -2896,7 +2991,7 @@ var WorkflowEngineImpl = class {
2896
2991
  await this.store.save(snapshot);
2897
2992
  try {
2898
2993
  const result = await withTimeout(
2899
- Promise.resolve(step.execute(snapshot.context, this.bus)),
2994
+ (signal) => Promise.resolve(step.execute(snapshot.context, this.bus, signal)),
2900
2995
  step.timeoutMs,
2901
2996
  step.name
2902
2997
  );