arkgate 2.8.3 → 2.9.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 (53) hide show
  1. package/CHANGELOG.md +46 -0
  2. package/README.md +2 -1
  3. package/bin/ark-check.mjs +2 -2
  4. package/bin/ark-layer-match.mjs +88 -5
  5. package/bin/ark-mcp.mjs +7 -70
  6. package/bin/ark-shared.mjs +88 -8
  7. package/bin/ark.mjs +3 -2
  8. package/bin/lib/architecture-scan.mjs +16 -4
  9. package/bin/lib/config-warnings.mjs +11 -2
  10. package/bin/lib/doctor-plan.mjs +20 -0
  11. package/bin/lib/import-resolve.mjs +133 -0
  12. package/bin/lib/presets.mjs +207 -11
  13. package/bin/lib/remediation.mjs +15 -0
  14. package/bin/lib/suggestions.mjs +8 -3
  15. package/dist/eslint/index.cjs +63 -5
  16. package/dist/eslint/index.cjs.map +1 -1
  17. package/dist/eslint/index.d.cts +33 -1
  18. package/dist/eslint/index.d.ts +33 -1
  19. package/dist/eslint/index.js +63 -5
  20. package/dist/eslint/index.js.map +1 -1
  21. package/dist/index.cjs +103 -14
  22. package/dist/index.cjs.map +1 -1
  23. package/dist/index.d.cts +21 -9
  24. package/dist/index.d.ts +21 -9
  25. package/dist/index.js +103 -14
  26. package/dist/index.js.map +1 -1
  27. package/dist/nestjs/index.cjs +78 -4
  28. package/dist/nestjs/index.cjs.map +1 -1
  29. package/dist/nestjs/index.d.cts +1 -1
  30. package/dist/nestjs/index.d.ts +1 -1
  31. package/dist/nestjs/index.js +78 -4
  32. package/dist/nestjs/index.js.map +1 -1
  33. package/dist/runtime/index.cjs +103 -14
  34. package/dist/runtime/index.cjs.map +1 -1
  35. package/dist/runtime/index.d.cts +1 -1
  36. package/dist/runtime/index.d.ts +1 -1
  37. package/dist/runtime/index.js +103 -14
  38. package/dist/runtime/index.js.map +1 -1
  39. package/dist/{types-CSJhEOk2.d.cts → types-D6Q8WHes.d.cts} +7 -0
  40. package/dist/{types-CSJhEOk2.d.ts → types-D6Q8WHes.d.ts} +7 -0
  41. package/docs/agent-guide.md +55 -4
  42. package/package.json +3 -1
  43. package/server.json +2 -2
  44. package/templates/architecture-playbook.json +65 -1
  45. package/templates/policy-packs/enthusiast-ddd-bounded-contexts.json +19 -0
  46. package/templates/policy-packs/enthusiast-ui-surface.json +18 -0
  47. package/templates/policy-packs/enthusiast-vertical-slice.json +18 -0
  48. package/templates/skills/ark-adopt.md +4 -0
  49. package/templates/skills/ark-architect.md +5 -1
  50. package/templates/skills/ark-autopilot.md +3 -1
  51. package/templates/skills/ark-fix.md +3 -0
  52. package/templates/skills/ark-place.md +7 -0
  53. package/templates/skills/ark-think.md +43 -0
@@ -1,2 +1,2 @@
1
1
  export { AICodeGate, AICodeGateContext, AICodeGateOptions, AICodeGateResult, AICodeGateViolation, AIGateExtension, Adapter, AdapterGovernanceIssue, AdapterGovernanceResult, ArkTestHarness, ArkTestSnapshot, BuildPublishPolicyContextOptions, ContractCheckResult, CreateAdapterOptions, CreateArkManifestOptions, DEFAULT_MAX_HISTORY_SIZE, DefinePolicyOptions, DefinePortOptions, EventContractRegistryImpl, EventContractViolationError, GraphPolicyContext, InMemoryAuditStore, InMemoryOutboxStore, InMemoryReadModelStore, InMemoryWorkflowStore, IntentNameValidation, InvalidIntentNameError, LayerFlowRule, LayerPolicyContextError, LayerPolicyOptions, MANIFEST_SCHEMA_VERSION, ObservedLayerFlowViolationError, PolicyViolationError, Port, PublishPolicyContext, SourceMetadataOverrideError, SyncRegistryOptions, UnknownEventSourceError, UnregisteredIntentError, architecturalPolicies, buildPublishPolicyContext, checkAdapterGovernance, checkContract, createAICodeGate, createAdapter, createArchitectureProfile, createArchitectureProfileFromArkConfig, createArkKernel, createArkKernelFromConfig, createArkManifest, createArkTestHarness, createAuditTrail, createDependencyGraph, createElevenLayerArkConfig, createEventBus, createEventContractRegistry, createIntentRegistry, createLenientArkKernel, createLenientArkKernelFromConfig, createMetadataRegistry, createObservabilityReporter, createProjectionRegistry, createSaga, createStrictArkKernel, createStrictArkKernelFromConfig, createWorkflowEngine, defaultIntentRegistry, defineArchitectureProfilePolicy, defineIntent, defineLayerPolicy, definePolicy, definePort, definePublishPolicy, elevenLayerProfile, isLayerPolicy, syncRegistryToGraph, validateIntentName, version } from '../index.cjs';
2
- export { _ as ArchitectureLayer, $ as ArchitectureLayerConfig, g as ArchitectureProfile, a0 as ArchitectureRule, h as ArkCheckConfig, A as ArkKernel, U as ArkKernelConfig, J as ArkManifest, a1 as ArkManifestArchitecture, a2 as ArkManifestData, a3 as ArkManifestEntityLink, a4 as ArkManifestGraph, a5 as ArkManifestIntent, a6 as ArkManifestPolicy, a7 as ArkManifestProjection, o as AuditQuery, n as AuditRecord, a8 as AuditRecordInput, a9 as AuditRecordType, m as AuditStore, q as AuditTrail, aa as CorrelationId, i as CreateArchitectureProfileFromArkConfigOptions, f as CreateArchitectureProfileOptions, V as CreateArkKernelFromConfigOptions, C as CreateArkKernelOptions, p as CreateAuditTrailOptions, j as CreateElevenLayerArkConfigOptions, y as CreateObservabilityReporterOptions, B as CreateProjectionRegistryOptions, N as CreateWorkflowEngineOptions, D as DefineIntentOptions, k as DependencyGraph, s as DomainEvent, ab as EntityMeta, x as EventBus, w as EventBusOptions, r as EventContract, ac as EventContractIssue, E as EventContractRegistry, t as EventContractValidationResult, 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, G as GraphEdge, ao as GraphNode, b as IntentCreator, b as IntentDefinition, a as IntentName, I as IntentRegistry, l as IntentRelationship, ap as IntentRelationshipKind, M as MetadataRegistry, Z as ObservabilityDriftReport, aq as ObservabilityFlow, z as ObservabilityReporter, ar as ObservedLayerFlowMode, u as OutboxRecord, v as OutboxStatus, O as OutboxStore, e as Policy, d as PolicyEnforcementMode, H as PolicyEngine, as as PolicyEvaluationResult, c as PolicySeverity, P as PolicyViolation, at as ProjectionCheckpoint, au as ProjectionDefinition, F as ProjectionRegistry, av as PublishedEventRecord, R as ReadModelStore, aw as RetryPolicy, L as SagaDefinition, Q as SagaInstance, ax as SagaStatus, ay as SagaStep, Y as TraceRecord, X as TraceRecordType, az as TraceSink, aA as Unsubscribe, aB as WorkflowDefinition, T as WorkflowEngine, K as WorkflowSnapshot, aC as WorkflowStatus, aD as WorkflowStep, W as WorkflowStore } from '../types-CSJhEOk2.cjs';
2
+ export { _ as ArchitectureLayer, $ as ArchitectureLayerConfig, g as ArchitectureProfile, a0 as ArchitectureRule, h as ArkCheckConfig, A as ArkKernel, U as ArkKernelConfig, J as ArkManifest, a1 as ArkManifestArchitecture, a2 as ArkManifestData, a3 as ArkManifestEntityLink, a4 as ArkManifestGraph, a5 as ArkManifestIntent, a6 as ArkManifestPolicy, a7 as ArkManifestProjection, o as AuditQuery, n as AuditRecord, a8 as AuditRecordInput, a9 as AuditRecordType, m as AuditStore, q as AuditTrail, aa as CorrelationId, i as CreateArchitectureProfileFromArkConfigOptions, f as CreateArchitectureProfileOptions, V as CreateArkKernelFromConfigOptions, C as CreateArkKernelOptions, p as CreateAuditTrailOptions, j as CreateElevenLayerArkConfigOptions, y as CreateObservabilityReporterOptions, B as CreateProjectionRegistryOptions, N as CreateWorkflowEngineOptions, D as DefineIntentOptions, k as DependencyGraph, s as DomainEvent, ab as EntityMeta, x as EventBus, w as EventBusOptions, r as EventContract, ac as EventContractIssue, E as EventContractRegistry, t as EventContractValidationResult, 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, G as GraphEdge, ao as GraphNode, b as IntentCreator, b as IntentDefinition, a as IntentName, I as IntentRegistry, l as IntentRelationship, ap as IntentRelationshipKind, M as MetadataRegistry, Z as ObservabilityDriftReport, aq as ObservabilityFlow, z as ObservabilityReporter, ar as ObservedLayerFlowMode, u as OutboxRecord, v as OutboxStatus, O as OutboxStore, e as Policy, d as PolicyEnforcementMode, H as PolicyEngine, as as PolicyEvaluationResult, c as PolicySeverity, P as PolicyViolation, at as ProjectionCheckpoint, au as ProjectionDefinition, F as ProjectionRegistry, av as PublishedEventRecord, R as ReadModelStore, aw as RetryPolicy, L as SagaDefinition, Q as SagaInstance, ax as SagaStatus, ay as SagaStep, Y as TraceRecord, X as TraceRecordType, az as TraceSink, aA as Unsubscribe, aB as WorkflowDefinition, T as WorkflowEngine, K as WorkflowSnapshot, aC as WorkflowStatus, aD as WorkflowStep, W as WorkflowStore } from '../types-D6Q8WHes.cjs';
@@ -1,2 +1,2 @@
1
1
  export { AICodeGate, AICodeGateContext, AICodeGateOptions, AICodeGateResult, AICodeGateViolation, AIGateExtension, Adapter, AdapterGovernanceIssue, AdapterGovernanceResult, ArkTestHarness, ArkTestSnapshot, BuildPublishPolicyContextOptions, ContractCheckResult, CreateAdapterOptions, CreateArkManifestOptions, DEFAULT_MAX_HISTORY_SIZE, DefinePolicyOptions, DefinePortOptions, EventContractRegistryImpl, EventContractViolationError, GraphPolicyContext, InMemoryAuditStore, InMemoryOutboxStore, InMemoryReadModelStore, InMemoryWorkflowStore, IntentNameValidation, InvalidIntentNameError, LayerFlowRule, LayerPolicyContextError, LayerPolicyOptions, MANIFEST_SCHEMA_VERSION, ObservedLayerFlowViolationError, PolicyViolationError, Port, PublishPolicyContext, SourceMetadataOverrideError, SyncRegistryOptions, UnknownEventSourceError, UnregisteredIntentError, architecturalPolicies, buildPublishPolicyContext, checkAdapterGovernance, checkContract, createAICodeGate, createAdapter, createArchitectureProfile, createArchitectureProfileFromArkConfig, createArkKernel, createArkKernelFromConfig, createArkManifest, createArkTestHarness, createAuditTrail, createDependencyGraph, createElevenLayerArkConfig, createEventBus, createEventContractRegistry, createIntentRegistry, createLenientArkKernel, createLenientArkKernelFromConfig, createMetadataRegistry, createObservabilityReporter, createProjectionRegistry, createSaga, createStrictArkKernel, createStrictArkKernelFromConfig, createWorkflowEngine, defaultIntentRegistry, defineArchitectureProfilePolicy, defineIntent, defineLayerPolicy, definePolicy, definePort, definePublishPolicy, elevenLayerProfile, isLayerPolicy, syncRegistryToGraph, validateIntentName, version } from '../index.js';
2
- export { _ as ArchitectureLayer, $ as ArchitectureLayerConfig, g as ArchitectureProfile, a0 as ArchitectureRule, h as ArkCheckConfig, A as ArkKernel, U as ArkKernelConfig, J as ArkManifest, a1 as ArkManifestArchitecture, a2 as ArkManifestData, a3 as ArkManifestEntityLink, a4 as ArkManifestGraph, a5 as ArkManifestIntent, a6 as ArkManifestPolicy, a7 as ArkManifestProjection, o as AuditQuery, n as AuditRecord, a8 as AuditRecordInput, a9 as AuditRecordType, m as AuditStore, q as AuditTrail, aa as CorrelationId, i as CreateArchitectureProfileFromArkConfigOptions, f as CreateArchitectureProfileOptions, V as CreateArkKernelFromConfigOptions, C as CreateArkKernelOptions, p as CreateAuditTrailOptions, j as CreateElevenLayerArkConfigOptions, y as CreateObservabilityReporterOptions, B as CreateProjectionRegistryOptions, N as CreateWorkflowEngineOptions, D as DefineIntentOptions, k as DependencyGraph, s as DomainEvent, ab as EntityMeta, x as EventBus, w as EventBusOptions, r as EventContract, ac as EventContractIssue, E as EventContractRegistry, t as EventContractValidationResult, 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, G as GraphEdge, ao as GraphNode, b as IntentCreator, b as IntentDefinition, a as IntentName, I as IntentRegistry, l as IntentRelationship, ap as IntentRelationshipKind, M as MetadataRegistry, Z as ObservabilityDriftReport, aq as ObservabilityFlow, z as ObservabilityReporter, ar as ObservedLayerFlowMode, u as OutboxRecord, v as OutboxStatus, O as OutboxStore, e as Policy, d as PolicyEnforcementMode, H as PolicyEngine, as as PolicyEvaluationResult, c as PolicySeverity, P as PolicyViolation, at as ProjectionCheckpoint, au as ProjectionDefinition, F as ProjectionRegistry, av as PublishedEventRecord, R as ReadModelStore, aw as RetryPolicy, L as SagaDefinition, Q as SagaInstance, ax as SagaStatus, ay as SagaStep, Y as TraceRecord, X as TraceRecordType, az as TraceSink, aA as Unsubscribe, aB as WorkflowDefinition, T as WorkflowEngine, K as WorkflowSnapshot, aC as WorkflowStatus, aD as WorkflowStep, W as WorkflowStore } from '../types-CSJhEOk2.js';
2
+ export { _ as ArchitectureLayer, $ as ArchitectureLayerConfig, g as ArchitectureProfile, a0 as ArchitectureRule, h as ArkCheckConfig, A as ArkKernel, U as ArkKernelConfig, J as ArkManifest, a1 as ArkManifestArchitecture, a2 as ArkManifestData, a3 as ArkManifestEntityLink, a4 as ArkManifestGraph, a5 as ArkManifestIntent, a6 as ArkManifestPolicy, a7 as ArkManifestProjection, o as AuditQuery, n as AuditRecord, a8 as AuditRecordInput, a9 as AuditRecordType, m as AuditStore, q as AuditTrail, aa as CorrelationId, i as CreateArchitectureProfileFromArkConfigOptions, f as CreateArchitectureProfileOptions, V as CreateArkKernelFromConfigOptions, C as CreateArkKernelOptions, p as CreateAuditTrailOptions, j as CreateElevenLayerArkConfigOptions, y as CreateObservabilityReporterOptions, B as CreateProjectionRegistryOptions, N as CreateWorkflowEngineOptions, D as DefineIntentOptions, k as DependencyGraph, s as DomainEvent, ab as EntityMeta, x as EventBus, w as EventBusOptions, r as EventContract, ac as EventContractIssue, E as EventContractRegistry, t as EventContractValidationResult, 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, G as GraphEdge, ao as GraphNode, b as IntentCreator, b as IntentDefinition, a as IntentName, I as IntentRegistry, l as IntentRelationship, ap as IntentRelationshipKind, M as MetadataRegistry, Z as ObservabilityDriftReport, aq as ObservabilityFlow, z as ObservabilityReporter, ar as ObservedLayerFlowMode, u as OutboxRecord, v as OutboxStatus, O as OutboxStore, e as Policy, d as PolicyEnforcementMode, H as PolicyEngine, as as PolicyEvaluationResult, c as PolicySeverity, P as PolicyViolation, at as ProjectionCheckpoint, au as ProjectionDefinition, F as ProjectionRegistry, av as PublishedEventRecord, R as ReadModelStore, aw as RetryPolicy, L as SagaDefinition, Q as SagaInstance, ax as SagaStatus, ay as SagaStep, Y as TraceRecord, X as TraceRecordType, az as TraceSink, aA as Unsubscribe, aB as WorkflowDefinition, T as WorkflowEngine, K as WorkflowSnapshot, aC as WorkflowStatus, aD as WorkflowStep, W as WorkflowStore } from '../types-D6Q8WHes.js';
@@ -1,5 +1,5 @@
1
1
  // src/version.ts
2
- var version = "2.8.3";
2
+ var version = "2.9.0";
3
3
 
4
4
  // src/kernel/intent/IntentRegistry.ts
5
5
  var IntentRegistry = class {
@@ -662,6 +662,82 @@ async function recordInterceptorError(interceptor, event, error, deps) {
662
662
  });
663
663
  }
664
664
 
665
+ // src/domain/layerMatch.ts
666
+ function normalizeGlobSeparators(pattern) {
667
+ let out = "";
668
+ for (let i = 0; i < pattern.length; i += 1) {
669
+ const c = pattern[i];
670
+ if (c === "\\" && i + 1 < pattern.length) {
671
+ const next = pattern[i + 1];
672
+ if ("*?{}[],".includes(next) || next === "\\") {
673
+ out += "\\" + next;
674
+ i += 1;
675
+ continue;
676
+ }
677
+ out += "/";
678
+ continue;
679
+ }
680
+ out += c;
681
+ }
682
+ return out;
683
+ }
684
+ function sliceIdForPath(relPath, sliceFolders) {
685
+ if (!sliceFolders?.length) return void 0;
686
+ const parts = String(relPath).split(/[/\\]/).filter(Boolean);
687
+ const folders = new Set(sliceFolders.map((s) => String(s).toLowerCase()));
688
+ for (let i = 0; i < parts.length - 1; i += 1) {
689
+ if (folders.has(parts[i].toLowerCase())) {
690
+ return `${parts[i]}/${parts[i + 1]}`;
691
+ }
692
+ }
693
+ return void 0;
694
+ }
695
+ function inferSliceFoldersFromPatterns(patterns) {
696
+ const out = /* @__PURE__ */ new Set();
697
+ for (const pattern of patterns ?? []) {
698
+ const glob = normalizeGlobSeparators(String(pattern));
699
+ const parts = glob.split("/").filter(Boolean);
700
+ for (let i = 0; i < parts.length; i += 1) {
701
+ const part = parts[i];
702
+ if ((part === "**" || part === "*") && i > 0) {
703
+ const prev = parts[i - 1];
704
+ if (prev && !prev.includes("*") && !prev.includes("{") && !prev.includes("}")) {
705
+ out.add(prev);
706
+ }
707
+ }
708
+ }
709
+ }
710
+ return [...out];
711
+ }
712
+ function resolveSliceFolders(rule, layerName, layers) {
713
+ if (Array.isArray(rule.sliceFolders) && rule.sliceFolders.length > 0) {
714
+ return rule.sliceFolders.filter((s) => typeof s === "string" && s.length > 0);
715
+ }
716
+ const layer = (layers ?? []).find((l) => l.name === layerName);
717
+ return inferSliceFoldersFromPatterns(layer?.patterns);
718
+ }
719
+ function findDeniedEdgeRule(rules, from, to, options) {
720
+ for (const rule of rules ?? []) {
721
+ if (rule.from !== from || rule.to !== to) continue;
722
+ if (rule.allowed !== false) continue;
723
+ if (rule.peerIsolation) {
724
+ const fromPath = options?.fromPath;
725
+ const toPath = options?.toPath;
726
+ if (!fromPath || !toPath) continue;
727
+ const folders = resolveSliceFolders(rule, from, options?.layers);
728
+ if (folders.length === 0) continue;
729
+ const fromSlice = sliceIdForPath(fromPath, folders);
730
+ const toSlice = sliceIdForPath(toPath, folders);
731
+ if (!fromSlice || !toSlice) continue;
732
+ if (fromSlice !== toSlice) return rule;
733
+ continue;
734
+ }
735
+ if (from === to) continue;
736
+ return rule;
737
+ }
738
+ return void 0;
739
+ }
740
+
665
741
  // src/kernel/event-bus/observedLayerFlow.ts
666
742
  async function assertObservedLayerFlowAllowed(event, deps) {
667
743
  if (deps.mode === "off" || !deps.architectureProfile) {
@@ -673,9 +749,7 @@ async function assertObservedLayerFlowAllowed(event, deps) {
673
749
  const fromLayer = profile.resolveLayer(source);
674
750
  const toLayer = profile.resolveLayer(event.intent);
675
751
  if (!fromLayer || !toLayer) return;
676
- const blocked = profile.rules.find(
677
- (rule) => !rule.allowed && rule.from === fromLayer && rule.to === toLayer
678
- );
752
+ const blocked = findDeniedEdgeRule(profile.rules, fromLayer, toLayer);
679
753
  if (!blocked) return;
680
754
  const severity = deps.mode;
681
755
  const message = blocked.message ?? `Observed layer violation: "${source}" (${fromLayer}) must not produce "${event.intent}" (${toLayer}).`;
@@ -2325,16 +2399,26 @@ function createAICodeGate(options = {}) {
2325
2399
  }
2326
2400
  }
2327
2401
  for (const specifier of extractModuleSpecifiers(source)) {
2328
- const targetLayer = options.resolveImportLayer?.(specifier.value, filePath);
2329
- if (targetLayer && contextLayer && targetLayer !== contextLayer) {
2330
- const blocked = options.architectureProfile?.rules.find(
2331
- (rule) => !rule.allowed && rule.from === contextLayer && rule.to === targetLayer
2402
+ const targetHit = options.resolveImportTarget?.(specifier.value, filePath) ?? (options.resolveImportLayer ? { layer: options.resolveImportLayer(specifier.value, filePath) } : void 0);
2403
+ const sourceHit = typeof filePath === "string" ? options.resolveImportTarget?.(filePath) ?? (options.resolveImportLayer ? { layer: contextLayer, relPath: void 0 } : void 0) : void 0;
2404
+ const targetLayer = targetHit?.layer;
2405
+ if (targetLayer && contextLayer) {
2406
+ const blocked = findDeniedEdgeRule(
2407
+ options.architectureProfile?.rules,
2408
+ contextLayer,
2409
+ targetLayer,
2410
+ {
2411
+ fromPath: sourceHit?.relPath,
2412
+ toPath: targetHit?.relPath,
2413
+ layers: options.architectureLayers
2414
+ }
2332
2415
  );
2333
2416
  if (blocked) {
2417
+ const peer = Boolean(blocked.peerIsolation);
2334
2418
  violations.push(
2335
2419
  violation(
2336
2420
  "LAYER_IMPORT_VIOLATION",
2337
- blocked.message ?? `Layer "${contextLayer}" must not import "${targetLayer}".`,
2421
+ blocked.message ?? (peer ? `Layer "${contextLayer}" must not import across slices into "${targetLayer}".` : `Layer "${contextLayer}" must not import "${targetLayer}".`),
2338
2422
  {
2339
2423
  line: lineOf(source, specifier.index),
2340
2424
  source: specifier.value,
@@ -2342,13 +2426,16 @@ function createAICodeGate(options = {}) {
2342
2426
  filePath,
2343
2427
  fromLayer: contextLayer,
2344
2428
  toLayer: targetLayer,
2345
- suggestion: "Depend on a port/interface owned by an inner layer instead, or move this code to a layer allowed to make this import.",
2346
- details: { importKind: specifier.kind }
2429
+ suggestion: peer ? "Extract shared code to a shared layer, or coordinate slices via events/ports \u2014 do not import across feature/context slices." : "Depend on a port/interface owned by an inner layer instead, or move this code to a layer allowed to make this import.",
2430
+ details: { importKind: specifier.kind, peerIsolation: peer }
2347
2431
  }
2348
2432
  )
2349
2433
  );
2434
+ continue;
2435
+ }
2436
+ if (targetLayer !== contextLayer) {
2437
+ continue;
2350
2438
  }
2351
- continue;
2352
2439
  }
2353
2440
  if (exemptFromInfraHeuristics) continue;
2354
2441
  if (!hasInfrastructureToken(specifier.value) && !isKnownInfrastructurePackage(specifier.value)) {
@@ -2417,8 +2504,10 @@ function createAICodeGate(options = {}) {
2417
2504
  if (!looksLikeIntentName(literal.value)) continue;
2418
2505
  const targetLayer = options.architectureProfile.resolveLayer(literal.value);
2419
2506
  if (!targetLayer) continue;
2420
- const blocked = options.architectureProfile.rules.find(
2421
- (rule) => !rule.allowed && rule.from === contextLayer && rule.to === targetLayer
2507
+ const blocked = findDeniedEdgeRule(
2508
+ options.architectureProfile.rules,
2509
+ contextLayer,
2510
+ targetLayer
2422
2511
  );
2423
2512
  if (blocked) {
2424
2513
  violations.push(