arkgate 3.3.0 → 3.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.
@@ -29,7 +29,10 @@ import {
29
29
  collectConfigWarnings,
30
30
  } from './config-warnings.mjs';
31
31
  import {
32
+ ambientCoveredByForbiddenGlobals,
33
+ collectCapabilityUses,
32
34
  collectForbiddenCapabilityUses,
35
+ effectiveCapabilityDeny,
33
36
  evaluateArchitectureGraph,
34
37
  extractSemanticDependencies,
35
38
  } from './analysis-engine.mjs';
@@ -69,6 +72,34 @@ export function scanSourceFile(ts, root, config, rules, manifestIntentLayers, fi
69
72
  });
70
73
  }
71
74
 
75
+ // U04 — opted-in capability walls (ADR 0009). One violation, one voice: an
76
+ // ambient use already covered by this layer's forbiddenGlobals reports only
77
+ // FORBIDDEN_GLOBAL (D7 dedup); absence of the surface adds nothing.
78
+ const capabilityDeny = new Set(effectiveCapabilityDeny(layerConfig ?? {}));
79
+ if (capabilityDeny.size > 0) {
80
+ for (const use of collectCapabilityUses(ts, sourceFile)) {
81
+ if (!capabilityDeny.has(use.capability)) continue;
82
+ if (
83
+ use.source === 'ambient-global' &&
84
+ ambientCoveredByForbiddenGlobals(use.symbol, forbiddenGlobals)
85
+ ) {
86
+ continue;
87
+ }
88
+ violations.push({
89
+ ruleId: 'CAPABILITY_VIOLATION',
90
+ file: normalize(path.relative(root, file)),
91
+ line: use.line,
92
+ fromLayer: sourceLayer,
93
+ target: use.symbol,
94
+ capability: use.capability,
95
+ message:
96
+ use.source === 'import-based'
97
+ ? `${sourceLayer} denies the ${use.capability} capability; found import of "${use.symbol}".`
98
+ : `${sourceLayer} denies the ${use.capability} capability; found ambient "${use.symbol}".`,
99
+ });
100
+ }
101
+ }
102
+
72
103
  const checkModuleEdge = (specifier, node, kind, typeOnly = false) => {
73
104
  const namedBindings = namedModuleBindings(ts, node);
74
105
  edges.push({
@@ -113,6 +113,31 @@ export const ARK_CONFIG_SCHEMA = {
113
113
  intentPrefixes: stringArraySchema,
114
114
  description: { type: 'string', minLength: 1 },
115
115
  forbiddenGlobals: stringArraySchema,
116
+ capabilities: {
117
+ type: 'object',
118
+ additionalProperties: false,
119
+ properties: {
120
+ deny: {
121
+ type: 'array',
122
+ uniqueItems: true,
123
+ items: {
124
+ type: 'string',
125
+ // Parity with src/domain/capabilities.ts CAPABILITY_IDS (guarded by tests;
126
+ // this literal keeps the generated CLI artifact self-contained).
127
+ enum: [
128
+ 'network',
129
+ 'filesystem',
130
+ 'clock',
131
+ 'randomness',
132
+ 'environment',
133
+ 'process',
134
+ 'persistence',
135
+ ],
136
+ },
137
+ },
138
+ },
139
+ },
140
+ pure: { type: 'boolean' },
116
141
  mayImportInfrastructure: { type: 'boolean' },
117
142
  optional: { type: 'boolean' },
118
143
  },
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Doctor's advisory sensors, aggregated (W01 contract health + U05 ambient
3
+ * state). Advisory only: nothing here feeds a verdict, designFitness, or an
4
+ * exit code. One seam keeps doctor-plan.mjs inside its module budget as new
5
+ * advisory surfaces land.
6
+ */
7
+ import { computeAmbientState, printAmbientStateSection } from './ambient-state.mjs';
8
+ import { computeContractHealth, printContractHealthSection } from './contract-smells.mjs';
9
+
10
+ export function computeDoctorAdvisories(root, config, cov, rules, files, ts) {
11
+ return {
12
+ contractHealth: computeContractHealth(root, config, cov, rules),
13
+ ambientState: computeAmbientState(ts, root, config, files),
14
+ };
15
+ }
16
+
17
+ export function printDoctorAdvisories(advisories, io) {
18
+ printContractHealthSection(advisories.contractHealth, io);
19
+ printAmbientStateSection(advisories.ambientState, io);
20
+ }
@@ -40,7 +40,7 @@ import {
40
40
  } from './post-green-path.mjs';
41
41
  import { loadGoldenPattern, summarizeGoldenPattern } from './golden-pattern.mjs';
42
42
  import { summarizePilotLoop } from './pilot-loop.mjs';
43
- import { computeContractHealth, printContractHealthSection } from './contract-smells.mjs';
43
+ import { computeDoctorAdvisories, printDoctorAdvisories } from './doctor-advisories.mjs';
44
44
 
45
45
  const color = {
46
46
  green: (s) => `\x1b[32m${s}\x1b[0m`,
@@ -425,8 +425,7 @@ export function runDoctor(root, config, files, rules, violations, asJson, option
425
425
  patternBets: patternBetsForLoop,
426
426
  designSmells,
427
427
  });
428
- // W01 contract meta-lint over the rules in force. Advisory; never feeds any verdict.
429
- const contractHealth = computeContractHealth(root, config, cov, rules);
428
+ const { contractHealth, ambientState } = computeDoctorAdvisories(root, config, cov, rules, files, options.ts); // W01+U05 advisories — never a verdict
430
429
 
431
430
  if (asJson) {
432
431
  console.log(
@@ -465,6 +464,8 @@ export function runDoctor(root, config, files, rules, violations, asJson, option
465
464
  pilotLoop,
466
465
  // W01: contract-health meta-lint (advisory; verdict unchanged).
467
466
  contractHealth,
467
+ // U05: ambient-state sensor (advisory; opt-in; verdict unchanged).
468
+ ambientState,
468
469
  governed: cov.governed,
469
470
  emptyLayers: cov.emptyLayers,
470
471
  layersWithoutRules: cov.layersWithoutRules,
@@ -646,8 +647,7 @@ export function runDoctor(root, config, files, rules, violations, asJson, option
646
647
  );
647
648
  }
648
649
 
649
- // W01 contract health (advisory; verdict unchanged).
650
- printContractHealthSection(contractHealth, { line, warn, color });
650
+ printDoctorAdvisories({ contractHealth, ambientState }, { line, warn, color }); // advisory sections
651
651
 
652
652
  console.log('');
653
653
  console.log(color.bold('Coverage'));
@@ -54,6 +54,8 @@ export function deterministicNextAction(violation) {
54
54
  return `Define a port in ${violation.fromLayer ?? 'the source layer'}, inject the ${violation.toLayer ?? 'outer-layer'} implementation, then preflight again.`;
55
55
  case 'FORBIDDEN_GLOBAL':
56
56
  return `Inject ${violation.target ?? 'the capability'} through a port, then preflight again.`;
57
+ case 'CAPABILITY_VIOLATION':
58
+ return `Define a ${String(violation.capability ?? 'capability')} port in ${violation.fromLayer ?? 'the walled layer'}, bind the implementation outside it, then preflight again.`;
57
59
  case 'CIRCULAR_DEPENDENCY':
58
60
  return 'Extract the shared dependency into a third module, then preflight again.';
59
61
  case 'RAW_EVENT_PUBLISH':
@@ -148,6 +150,13 @@ export function classifyRemediation(violation) {
148
150
  rationale: 'Ambient global in a pure layer: inject the capability through a port (Clock, Config, Http). Introducing the port is a design decision.',
149
151
  };
150
152
  }
153
+ if (ruleId === 'CAPABILITY_VIOLATION') {
154
+ return {
155
+ class: 'judgment',
156
+ confidence: 0.8,
157
+ rationale: 'A denied effect capability (clock/network/persistence/…) reached a walled layer: define a port and bind the implementation outside it. Never mechanical-safe — the port shape is a design decision.',
158
+ };
159
+ }
151
160
  if (ruleId === 'CIRCULAR_DEPENDENCY') {
152
161
  return {
153
162
  class: 'judgment',
@@ -201,6 +210,11 @@ export function enrichViolationWithFixClass(violation) {
201
210
  enriched.effort = 'small';
202
211
  enriched.enthusiastHint = `Do not call "${violation.target ?? 'that global'}" here. Pass the capability in through a small interface (for example a Clock, HttpPort, or Config provider).`;
203
212
  break;
213
+ case 'CAPABILITY_VIOLATION':
214
+ enriched.fixClass = 'inject-port';
215
+ enriched.effort = 'medium';
216
+ enriched.enthusiastHint = `This layer denies the ${String(violation.capability ?? 'effect')} capability. Define a small port (for example ClockPort, HttpPort, StoragePort) and inject the implementation from an adapter layer instead of using "${violation.target ?? 'the capability'}" directly.`;
217
+ break;
204
218
  case 'RAW_EVENT_PUBLISH':
205
219
  enriched.fixClass = 'registered-intent';
206
220
  enriched.effort = 'small';
@@ -129,9 +129,10 @@ export function scanCacheKey(root, args) {
129
129
  // v3: per-file exportsOnlyTypes. v4: typeOnlyExportNames + namedBindings.
130
130
  // v5: hasTopLevelSideEffects. v6: non-exported impure inits + non-export class statics.
131
131
  // v7: scope-aware forbidden globals + import-equals dependency edges.
132
+ // v8: opted-in capability walls (U04) — stale caches must not miss wall verdicts.
132
133
  return crypto
133
134
  .createHash('sha1')
134
- .update(`ark-check-cache-v7\0${read(configPath)}\0${manifestPath ? read(manifestPath) : ''}`)
135
+ .update(`ark-check-cache-v8\0${read(configPath)}\0${manifestPath ? read(manifestPath) : ''}`)
135
136
  .digest('hex');
136
137
  }
137
138
 
@@ -45,6 +45,8 @@ export const FIX_HINTS = {
45
45
  'Use a source intent that belongs to the same layer as the publishing file, or move the file.',
46
46
  FORBIDDEN_GLOBAL:
47
47
  'Inject the capability through a port (e.g. a Clock, IdGenerator, or HttpPort) instead of reaching for the ambient global.',
48
+ CAPABILITY_VIOLATION:
49
+ 'This layer denies that effect. Define a small port (ClockPort, HttpPort, StoragePort) and bind the implementation in an adapter layer.',
48
50
  CIRCULAR_DEPENDENCY:
49
51
  'Break the cycle: extract the shared code into a module both sides import, invert one edge behind a port/interface, or merge the files if they are really one unit.',
50
52
  };
@@ -8,6 +8,9 @@
8
8
  */
9
9
  type ArkConfigSchemaVersion = '1.0';
10
10
  type ArkConfigCyclePolicy = 'strict' | 'soft' | 'framework-soft' | 'off';
11
+ type ArkConfigLayerCapabilities = {
12
+ deny?: string[];
13
+ };
11
14
  type ArkConfigLayer = {
12
15
  name: string;
13
16
  patterns: string[];
@@ -15,6 +18,10 @@ type ArkConfigLayer = {
15
18
  intentPrefixes?: string[];
16
19
  description?: string;
17
20
  forbiddenGlobals?: string[];
21
+ /** ADR 0009 D2 — opt-in effect-capability walls; absence changes no verdict. */
22
+ capabilities?: ArkConfigLayerCapabilities;
23
+ /** Dual-depth sugar: `pure: true` denies all seven capabilities. */
24
+ pure?: boolean;
18
25
  mayImportInfrastructure?: boolean;
19
26
  optional?: boolean;
20
27
  };
@@ -8,6 +8,9 @@
8
8
  */
9
9
  type ArkConfigSchemaVersion = '1.0';
10
10
  type ArkConfigCyclePolicy = 'strict' | 'soft' | 'framework-soft' | 'off';
11
+ type ArkConfigLayerCapabilities = {
12
+ deny?: string[];
13
+ };
11
14
  type ArkConfigLayer = {
12
15
  name: string;
13
16
  patterns: string[];
@@ -15,6 +18,10 @@ type ArkConfigLayer = {
15
18
  intentPrefixes?: string[];
16
19
  description?: string;
17
20
  forbiddenGlobals?: string[];
21
+ /** ADR 0009 D2 — opt-in effect-capability walls; absence changes no verdict. */
22
+ capabilities?: ArkConfigLayerCapabilities;
23
+ /** Dual-depth sugar: `pure: true` denies all seven capabilities. */
24
+ pure?: boolean;
18
25
  mayImportInfrastructure?: boolean;
19
26
  optional?: boolean;
20
27
  };
@@ -1,3 +1,3 @@
1
- "use strict";var de=Object.create;var k=Object.defineProperty;var ge=Object.getOwnPropertyDescriptor;var pe=Object.getOwnPropertyNames;var me=Object.getPrototypeOf,ye=Object.prototype.hasOwnProperty;var he=(e,t)=>{for(var n in t)k(e,n,{get:t[n],enumerable:!0})},v=(e,t,n,i)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of pe(t))!ye.call(e,r)&&r!==n&&k(e,r,{get:()=>t[r],enumerable:!(i=ge(t,r))||i.enumerable});return e};var B=(e,t,n)=>(n=e!=null?de(me(e)):{},v(t||!e||!e.__esModule?k(n,"default",{value:e,enumerable:!0}):n,e)),Ae=e=>v(k({},"__esModule",{value:!0}),e);var Fe={};he(Fe,{default:()=>Ve,findConfigPath:()=>D,globToRegExp:()=>R,isEdgeDenied:()=>P,layerForRelativePath:()=>S,loadArkConfig:()=>G,noDomainInfraImports:()=>le,noForbiddenGlobals:()=>fe,noRawEventPublish:()=>ce,patternSpecificity:()=>$,plugin:()=>E,requirePublishSource:()=>ue,resolveRelativeImport:()=>re});module.exports=Ae(Fe);var b=B(require("fs"),1),c=B(require("path"),1);var K=new Map;function W(e){return/[.*+?^${}()|[\]\\]/.test(e)?`\\${e}`:e}function O(e){let t="";for(let n=0;n<e.length;n+=1){let i=e[n];if(i==="\\"&&n+1<e.length){let r=e[n+1];if("*?{}[],".includes(r)||r==="\\"){t+="\\"+r,n+=1;continue}t+="/";continue}t+=i}return t}function be(e){let t=0;for(let n=0;n<e.length;n+=1){let i=e[n];if(i==="\\"){n+=1;continue}if(i==="{")t+=1;else if(i==="}"&&(t-=1,t<0))return!1}return t===0}function R(e){let t=K.get(e);if(t)return t;let n=O(e),i=be(n),r="",o=0;for(let a=0;a<n.length;a+=1){let f=n[a];f==="\\"&&a+1<n.length?(r+=W(n[a+1]),a+=1):f==="*"?n[a+1]==="*"?n[a+2]==="/"?(r+="(?:.*/)?",a+=2):(r+=".*",a+=1):r+="[^/]*":f==="?"?r+="[^/]":f==="{"&&i?(r+="(?:",o+=1):f==="}"&&i&&o>0?(r+=")",o-=1):f===","&&i&&o>0?r+="|":r+=W(f)}let s=new RegExp(`^${r}$`);return K.set(e,s),s}function $(e){let t=O(String(e)),i=t.split("*")[0].split("/").filter(Boolean).length,r=t.replace(/\*/g,"").length;return i*1e4+r}function S(e,t){let n=String(e).split(/[/\\]/).join("/"),i,r=-1;for(let o of t??[])if(!(o.exclude??[]).some(s=>R(s).test(n))){for(let s of o.patterns??[])if(R(s).test(n)){let a=$(s);a>r&&(r=a,i=o.name)}}return i}function q(e,t){if(!t?.length)return;let n=String(e).split(/[/\\]/).filter(Boolean),i=new Set(t.map(r=>String(r).toLowerCase()));for(let r=0;r<n.length-1;r+=1)if(i.has(n[r].toLowerCase()))return`${n[r]}/${n[r+1]}`}function Se(e){let t=new Set;for(let n of e??[]){let r=O(String(n)).split("/").filter(Boolean);for(let o=0;o<r.length;o+=1){let s=r[o];if((s==="**"||s==="*")&&o>0){let a=r[o-1];a&&!a.includes("*")&&!a.includes("{")&&!a.includes("}")&&t.add(a)}}}return[...t]}function ke(e,t,n){if(Array.isArray(e.sliceFolders)&&e.sliceFolders.length>0)return e.sliceFolders.filter(r=>typeof r=="string"&&r.length>0);let i=(n??[]).find(r=>r.name===t);return Se(i?.patterns)}function Re(e,t,n,i){for(let r of e??[])if(!(r.from!==t||r.to!==n)&&r.allowed===!1){if(r.peerIsolation){let o=i?.fromPath,s=i?.toPath;if(!o||!s)continue;let a=ke(r,t,i?.layers);if(a.length===0)continue;let f=q(o,a),g=q(s,a);if(!f||!g)continue;if(f!==g)return r;continue}if(t!==n)return r}}function P(e,t,n,i){return Re(e,t,n,i)!==void 0}var V="https://unpkg.com/arkgate@2/schemas/ark.config.schema.json",J=["DomainModel","ApplicationOrchestration","PersistenceAdapters","IntegrationAdapters","WorkflowSagaEngine","BackgroundJobsScheduling","PresentationAdapters","ReportingReadModels","ExtensibilityMetadata","SecurityAuditObservability","Kernel"],Ie=new Set(["PresentationAdapters->ApplicationOrchestration","ApplicationOrchestration->DomainModel","WorkflowSagaEngine->ApplicationOrchestration","WorkflowSagaEngine->DomainModel","BackgroundJobsScheduling->ApplicationOrchestration"]);function Ce(){let e=[];for(let t of J)for(let n of J)t===n||Ie.has(`${t}->${n}`)||e.push({from:t,to:n,allowed:!1});return e}var z=Ce();var y={type:"array",items:{type:"string",minLength:1},uniqueItems:!0},Y={$schema:"https://json-schema.org/draft/2020-12/schema",$id:V,title:"ArkGate architecture contract",description:"Versioned contract consumed identically by ArkGate CLI, MCP, and ESLint surfaces.",type:"object",additionalProperties:!1,required:["$schema","schemaVersion","include","layers","rules"],properties:{$schema:{type:"string",minLength:1,default:V,description:"Editor-facing URL or local path for this JSON Schema."},schemaVersion:{type:"string",const:"1.0",default:"1.0"},name:{type:"string",minLength:1},include:{...y,minItems:1,default:["src"]},exclude:{...y,default:[]},excludeGenerated:{type:"boolean",default:!0},frameworkOverlay:{type:"string",minLength:1},layers:{type:"array",default:[],items:{$ref:"#/$defs/layer"}},rules:{type:"array",default:z,items:{$ref:"#/$defs/rule"}},cyclePolicy:{type:"string",enum:["strict","soft","framework-soft","off"],default:"strict"},dynamicImportAllowlist:{...y,default:[]},safety:{$ref:"#/$defs/safety",default:{maxTsSuppressions:0,maxAnyCasts:0,allowInMemory:!1,allowDisabledPeerIsolation:!1}}},$defs:{layer:{type:"object",additionalProperties:!1,required:["name","patterns"],properties:{name:{type:"string",minLength:1},patterns:{...y,minItems:1},exclude:y,intentPrefixes:y,description:{type:"string",minLength:1},forbiddenGlobals:y,mayImportInfrastructure:{type:"boolean"},optional:{type:"boolean"}}},rule:{type:"object",additionalProperties:!1,required:["from","to","allowed"],properties:{from:{type:"string",minLength:1},to:{type:"string",minLength:1},allowed:{type:"boolean"},message:{type:"string",minLength:1},peerIsolation:{type:"boolean"},sliceFolders:{...y,minItems:1}}},safety:{type:"object",additionalProperties:!1,properties:{maxTsSuppressions:{type:"integer",minimum:0,default:0},maxAnyCasts:{type:"integer",minimum:0,default:0},allowInMemory:{type:"boolean",default:!1},allowDisabledPeerIsolation:{type:"boolean",default:!1}}}}},A=class extends Error{issues;source;constructor(t,n){super(`Invalid ArkGate config (${t}):
1
+ "use strict";var be=Object.create;var C=Object.defineProperty;var he=Object.getOwnPropertyDescriptor;var Ae=Object.getOwnPropertyNames;var ke=Object.getPrototypeOf,Se=Object.prototype.hasOwnProperty;var Ie=(e,t)=>{for(var n in t)C(e,n,{get:t[n],enumerable:!0})},U=(e,t,n,i)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of Ae(t))!Se.call(e,r)&&r!==n&&C(e,r,{get:()=>t[r],enumerable:!(i=he(t,r))||i.enumerable});return e};var q=(e,t,n)=>(n=e!=null?be(ke(e)):{},U(t||!e||!e.__esModule?C(n,"default",{value:e,enumerable:!0}):n,e)),we=e=>U(C({},"__esModule",{value:!0}),e);var Be={};Ie(Be,{default:()=>Ge,findConfigPath:()=>L,globToRegExp:()=>R,isEdgeDenied:()=>F,layerForRelativePath:()=>h,loadArkConfig:()=>_,noDeniedCapabilities:()=>ye,noDomainInfraImports:()=>fe,noForbiddenGlobals:()=>me,noRawEventPublish:()=>pe,patternSpecificity:()=>j,plugin:()=>N,requirePublishSource:()=>ge,resolveRelativeImport:()=>ae});module.exports=we(Be);var S=q(require("fs"),1),u=q(require("path"),1);var W=new Map;function Y(e){return/[.*+?^${}()|[\]\\]/.test(e)?`\\${e}`:e}function P(e){let t="";for(let n=0;n<e.length;n+=1){let i=e[n];if(i==="\\"&&n+1<e.length){let r=e[n+1];if("*?{}[],".includes(r)||r==="\\"){t+="\\"+r,n+=1;continue}t+="/";continue}t+=i}return t}function Ce(e){let t=0;for(let n=0;n<e.length;n+=1){let i=e[n];if(i==="\\"){n+=1;continue}if(i==="{")t+=1;else if(i==="}"&&(t-=1,t<0))return!1}return t===0}function R(e){let t=W.get(e);if(t)return t;let n=P(e),i=Ce(n),r="",s=0;for(let c=0;c<n.length;c+=1){let p=n[c];p==="\\"&&c+1<n.length?(r+=Y(n[c+1]),c+=1):p==="*"?n[c+1]==="*"?n[c+2]==="/"?(r+="(?:.*/)?",c+=2):(r+=".*",c+=1):r+="[^/]*":p==="?"?r+="[^/]":p==="{"&&i?(r+="(?:",s+=1):p==="}"&&i&&s>0?(r+=")",s-=1):p===","&&i&&s>0?r+="|":r+=Y(p)}let l=new RegExp(`^${r}$`);return W.set(e,l),l}function j(e){let t=P(String(e)),i=t.split("*")[0].split("/").filter(Boolean).length,r=t.replace(/\*/g,"").length;return i*1e4+r}function h(e,t){let n=String(e).split(/[/\\]/).join("/"),i,r=-1;for(let s of t??[])if(!(s.exclude??[]).some(l=>R(l).test(n))){for(let l of s.patterns??[])if(R(l).test(n)){let c=j(l);c>r&&(r=c,i=s.name)}}return i}function z(e,t){if(!t?.length)return;let n=String(e).split(/[/\\]/).filter(Boolean),i=new Set(t.map(r=>String(r).toLowerCase()));for(let r=0;r<n.length-1;r+=1)if(i.has(n[r].toLowerCase()))return`${n[r]}/${n[r+1]}`}function Re(e){let t=new Set;for(let n of e??[]){let r=P(String(n)).split("/").filter(Boolean);for(let s=0;s<r.length;s+=1){let l=r[s];if((l==="**"||l==="*")&&s>0){let c=r[s-1];c&&!c.includes("*")&&!c.includes("{")&&!c.includes("}")&&t.add(c)}}}return[...t]}function xe(e,t,n){if(Array.isArray(e.sliceFolders)&&e.sliceFolders.length>0)return e.sliceFolders.filter(r=>typeof r=="string"&&r.length>0);let i=(n??[]).find(r=>r.name===t);return Re(i?.patterns)}function Ee(e,t,n,i){for(let r of e??[])if(!(r.from!==t||r.to!==n)&&r.allowed===!1){if(r.peerIsolation){let s=i?.fromPath,l=i?.toPath;if(!s||!l)continue;let c=xe(r,t,i?.layers);if(c.length===0)continue;let p=z(s,c),g=z(l,c);if(!p||!g)continue;if(p!==g)return r;continue}if(t!==n)return r}}function F(e,t,n,i){return Ee(e,t,n,i)!==void 0}var J=Object.freeze(["network","filesystem","clock","randomness","environment","process","persistence"]),Ne=Object.freeze({fetch:"network",XMLHttpRequest:"network",Date:"clock","Date.now":"clock","Math.random":"randomness","process.env":"environment",process:"process"}),Ue=Object.freeze(Object.keys(Ne).sort()),V=Object.freeze({fs:"filesystem","node:fs":"filesystem","fs/promises":"filesystem","node:fs/promises":"filesystem","fs-extra":"filesystem","graceful-fs":"filesystem",memfs:"filesystem",chokidar:"filesystem",http:"network",https:"network",http2:"network",net:"network",tls:"network",dgram:"network",dns:"network","node:http":"network","node:https":"network","node:http2":"network","node:net":"network","node:tls":"network","node:dgram":"network","node:dns":"network",axios:"network",undici:"network","node-fetch":"network",got:"network",ky:"network",superagent:"network",ws:"network",process:"process","node:process":"process",child_process:"process","node:child_process":"process","@prisma/client":"persistence",prisma:"persistence",pg:"persistence",mysql:"persistence",mysql2:"persistence",mongodb:"persistence",mongoose:"persistence",sqlite3:"persistence","better-sqlite3":"persistence",redis:"persistence",ioredis:"persistence",typeorm:"persistence",knex:"persistence","drizzle-orm":"persistence",sequelize:"persistence",kysely:"persistence","@supabase/supabase-js":"persistence"});function Z(e){if(!e||e.startsWith(".")||e.startsWith("/"))return null;let t=V[e];if(t)return t;let n=e.indexOf("/");if(n<0)return null;let i=e.slice(0,n),r=V[i];if(r)return r;let s=e.indexOf("/",n+1);return s<0?null:V[e.slice(0,s)]??null}function X(e){if(e?.pure===!0)return[...J].sort();let n=(e?.capabilities?.deny??[]).filter(i=>J.includes(i));return[...new Set(n)].sort()}var M="https://unpkg.com/arkgate@2/schemas/ark.config.schema.json",Q=["DomainModel","ApplicationOrchestration","PersistenceAdapters","IntegrationAdapters","WorkflowSagaEngine","BackgroundJobsScheduling","PresentationAdapters","ReportingReadModels","ExtensibilityMetadata","SecurityAuditObservability","Kernel"],Le=new Set(["PresentationAdapters->ApplicationOrchestration","ApplicationOrchestration->DomainModel","WorkflowSagaEngine->ApplicationOrchestration","WorkflowSagaEngine->DomainModel","BackgroundJobsScheduling->ApplicationOrchestration"]);function _e(){let e=[];for(let t of Q)for(let n of Q)t===n||Le.has(`${t}->${n}`)||e.push({from:t,to:n,allowed:!1});return e}var te=_e();var b={type:"array",items:{type:"string",minLength:1},uniqueItems:!0},ee={$schema:"https://json-schema.org/draft/2020-12/schema",$id:M,title:"ArkGate architecture contract",description:"Versioned contract consumed identically by ArkGate CLI, MCP, and ESLint surfaces.",type:"object",additionalProperties:!1,required:["$schema","schemaVersion","include","layers","rules"],properties:{$schema:{type:"string",minLength:1,default:M,description:"Editor-facing URL or local path for this JSON Schema."},schemaVersion:{type:"string",const:"1.0",default:"1.0"},name:{type:"string",minLength:1},include:{...b,minItems:1,default:["src"]},exclude:{...b,default:[]},excludeGenerated:{type:"boolean",default:!0},frameworkOverlay:{type:"string",minLength:1},layers:{type:"array",default:[],items:{$ref:"#/$defs/layer"}},rules:{type:"array",default:te,items:{$ref:"#/$defs/rule"}},cyclePolicy:{type:"string",enum:["strict","soft","framework-soft","off"],default:"strict"},dynamicImportAllowlist:{...b,default:[]},safety:{$ref:"#/$defs/safety",default:{maxTsSuppressions:0,maxAnyCasts:0,allowInMemory:!1,allowDisabledPeerIsolation:!1}}},$defs:{layer:{type:"object",additionalProperties:!1,required:["name","patterns"],properties:{name:{type:"string",minLength:1},patterns:{...b,minItems:1},exclude:b,intentPrefixes:b,description:{type:"string",minLength:1},forbiddenGlobals:b,capabilities:{type:"object",additionalProperties:!1,properties:{deny:{type:"array",uniqueItems:!0,items:{type:"string",enum:["network","filesystem","clock","randomness","environment","process","persistence"]}}}},pure:{type:"boolean"},mayImportInfrastructure:{type:"boolean"},optional:{type:"boolean"}}},rule:{type:"object",additionalProperties:!1,required:["from","to","allowed"],properties:{from:{type:"string",minLength:1},to:{type:"string",minLength:1},allowed:{type:"boolean"},message:{type:"string",minLength:1},peerIsolation:{type:"boolean"},sliceFolders:{...b,minItems:1}}},safety:{type:"object",additionalProperties:!1,properties:{maxTsSuppressions:{type:"integer",minimum:0,default:0},maxAnyCasts:{type:"integer",minimum:0,default:0},allowInMemory:{type:"boolean",default:!1},allowDisabledPeerIsolation:{type:"boolean",default:!1}}}}},k=class extends Error{issues;source;constructor(t,n){super(`Invalid ArkGate config (${t}):
2
2
  ${n.map(i=>`- ${i.path}: ${i.message}`).join(`
3
- `)}`),this.name="ArkConfigValidationError",this.source=t,this.issues=n}};function Z(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}function j(e,t){return/^[A-Za-z_$][A-Za-z0-9_$]*$/.test(t)?`${e}.${t}`:`${e}[${JSON.stringify(t)}]`}function h(e){return e===null?"null":Array.isArray(e)?"array":typeof e}function Ee(e,t){let n="#/$defs/";if(e.startsWith(n))return t.$defs[e.slice(n.length)]}function I(e,t,n,i,r){if(t.$ref){let o=Ee(t.$ref,i);if(!o){r.push({path:n,message:`schema reference ${t.$ref} cannot be resolved`});return}I(e,o,n,i,r);return}if(t.const!==void 0&&!Object.is(e,t.const)){r.push({path:n,message:`must equal ${JSON.stringify(t.const)}`});return}if(t.enum&&!t.enum.some(o=>Object.is(o,e))){r.push({path:n,message:`must be one of ${t.enum.map(String).join(", ")}`});return}if(t.type==="object"){if(!Z(e)){r.push({path:n,message:`must be an object; received ${h(e)}`});return}let o=t.properties??{};for(let s of t.required??[])e[s]===void 0&&r.push({path:j(n,s),message:"is required"});if(t.additionalProperties===!1)for(let s of Object.keys(e))s in o||r.push({path:j(n,s),message:"unknown field"});for(let[s,a]of Object.entries(o))e[s]!==void 0&&I(e[s],a,j(n,s),i,r);return}if(t.type==="array"){if(!Array.isArray(e)){r.push({path:n,message:`must be an array; received ${h(e)}`});return}if(t.minItems!==void 0&&e.length<t.minItems&&r.push({path:n,message:`must contain at least ${t.minItems} item(s)`}),t.uniqueItems){let o=e.map(s=>JSON.stringify(s));new Set(o).size!==o.length&&r.push({path:n,message:"must not contain duplicate items"})}t.items&&e.forEach((o,s)=>I(o,t.items,`${n}[${s}]`,i,r));return}if(t.type==="string"){if(typeof e!="string"){r.push({path:n,message:`must be a string; received ${h(e)}`});return}t.minLength!==void 0&&e.length<t.minLength&&r.push({path:n,message:`must contain at least ${t.minLength} character(s)`});return}if(t.type==="boolean"){typeof e!="boolean"&&r.push({path:n,message:`must be a boolean; received ${h(e)}`});return}if(t.type==="integer"){if(!Number.isInteger(e)){r.push({path:n,message:`must be an integer; received ${h(e)}`});return}t.minimum!==void 0&&e<t.minimum&&r.push({path:n,message:`must be at least ${t.minimum}`})}}function Ne(e){return{...e,$schema:e.$schema===void 0?V:e.$schema,schemaVersion:e.schemaVersion===void 0?"1.0":e.schemaVersion,include:e.include===void 0?["src"]:e.include,layers:e.layers===void 0?[]:e.layers,rules:e.rules===void 0?z.map(t=>({...t})):e.rules}}function xe(e,t="ark.config.json"){if(!Z(e))throw new A(t,[{path:"$",message:`must be an object; received ${h(e)}`}]);let n=e.schemaVersion===void 0?"unversioned":null;if(e.schemaVersion!==void 0&&e.schemaVersion!=="1.0")throw new A(t,[{path:"$.schemaVersion",message:`unsupported version ${JSON.stringify(e.schemaVersion)}; expected 1.0`}]);return{candidate:Ne(e),migratedFrom:n}}function we(e,t="ark.config.json"){let{candidate:n,migratedFrom:i}=xe(e,t),r=[];if(I(n,Y,"$",Y,r),r.length>0)throw new A(t,r);return{config:n,migratedFrom:i}}function Q(e,t="ark.config.json"){let n;try{n=JSON.parse(e)}catch(i){throw new A(t,[{path:"$",message:`invalid JSON: ${i instanceof Error?i.message:String(i)}`}])}return we(n,t)}function m(e){return typeof e=="string"&&e.length>0?e:void 0}function X(e,t){return Number.isInteger(e)&&Number(e)>0?Number(e):t}function Le(e,t,n){return e==="LAYER_IMPORT_VIOLATION"?t.typeOnly||n.targetTypeOnlyExports===!0||n.namedBindingsTypeOnly===!0?"Move the referenced type to a mutually allowed layer, use `import type`, then preflight again.":n.peerIsolation===!0?"Extract the shared dependency to a shared layer, then preflight again.":`Define a port in ${t.fromLayer??"the source layer"}, inject the ${t.toLayer??"outer-layer"} implementation, then preflight again.`:e==="FORBIDDEN_GLOBAL"?`Inject ${t.target??"the capability"} through a port, then preflight again.`:e==="CIRCULAR_DEPENDENCY"?"Extract the shared dependency into a third module, then preflight again.":e==="RAW_EVENT_PUBLISH"?"Publish through a registered intent creator, then run Ark again.":e==="PUBLISH_MISSING_SOURCE"?"Add metadata.source to the publish call, then run Ark again.":`Resolve ${e} without weakening ark.config.json, then run Ark again.`}function ee(e,t="error"){let n=m(e.ruleId)??m(e.code)??"ARK_UNKNOWN",i=e.severity==="warning"?"warning":t,r={...m(e.target)?{target:m(e.target)}:{},...m(e.fromLayer)?{fromLayer:m(e.fromLayer)}:{},...m(e.toLayer)?{toLayer:m(e.toLayer)}:{},...typeof e.typeOnly=="boolean"?{typeOnly:e.typeOnly}:{}};return{ruleId:n,severity:i,message:m(e.message)??n,location:{file:m(e.file)??"<unknown>",line:X(e.line,1),column:X(e.column,1)},evidence:r,nextAction:m(e.nextAction)??Le(n,r,e)}}var te={RAW_EVENT_PUBLISH:"Publish through a registered intent creator; raw event objects or intent strings bypass Ark contracts and tooling.",PUBLISH_MISSING_SOURCE:"Strict Ark publish calls must include metadata.source."};function _e(e){return/^(Domain|Application|Adapter|Workflow|Job|Presentation|Reporting|Metadata|Security|Audit|Observability|Kernel)\.[A-Za-z0-9_.]+$/.test(e)}function F(e){if(!e.publishCall)return[];let t=[];return(e.rawIntentName!==void 0&&_e(e.rawIntentName)||e.objectHasIntent)&&t.push({ruleId:"RAW_EVENT_PUBLISH",message:te.RAW_EVENT_PUBLISH}),e.arkPublishCandidate&&!e.hasSource&&t.push({ruleId:"PUBLISH_MISSING_SOURCE",message:te.PUBLISH_MISSING_SOURCE}),t}function N(e){if(typeof e.physicalFilename=="string"&&e.physicalFilename.length>0)return e.physicalFilename;if(typeof e.filename=="string"&&e.filename.length>0)return e.filename;if(typeof e.getFilename=="function")try{let t=e.getFilename();if(typeof t=="string"&&t.length>0)return t}catch{}return""}function x(e,t,n,i,r){let o=ee({...i,line:i.line??t.loc?.start?.line,column:i.column??(typeof t.loc?.start?.column=="number"?t.loc.start.column+1:void 0)});return e.report({node:t,messageId:n,...r?{data:r}:{},diagnostic:o}),o}function D(e){if(!e||e==="<input>"||e.startsWith("stdin"))return null;let t=c.default.dirname(c.default.resolve(e));for(;;){let n=c.default.join(t,"ark.config.json");if(b.default.existsSync(n))return n;let i=c.default.dirname(t);if(i===t)return null;t=i}}var M=new Map;function G(e){if(M.has(e))return M.get(e)??null;if(!b.default.existsSync(e))return null;let t=Q(b.default.readFileSync(e,"utf8"),e).config;return M.set(e,t),t}function re(e,t){if(!t.startsWith("."))return null;let n=c.default.resolve(c.default.dirname(e),t),i=[n,`${n}.ts`,`${n}.tsx`,`${n}.mts`,`${n}.cts`,`${n}.js`,`${n}.jsx`,c.default.join(n,"index.ts"),c.default.join(n,"index.tsx"),c.default.join(n,"index.js")];for(let r of i)try{if(b.default.existsSync(r)&&b.default.statSync(r).isFile())return r}catch{}return`${n}.ts`}function w(e){return typeof e?.value=="string"?e.value:void 0}function T(e){return e?.name??w(e)}function H(e){return e.sourceCode??e.getSourceCode?.()}function ie(e,t){let n=H(e)?.getScope?.(t);for(;n;){let i=n.references?.find(r=>r.identifier===t);if(i)return i;n=n.upper??void 0}}function ne(e,t,n){let i=ie(e,t);if(i?.resolved)return(i.resolved.defs?.length??0)>0;let r=H(e)?.getScope?.(t);for(;r;){let o=r.set?.get(n);if(o)return(o.defs?.length??0)>0;r=r.upper??void 0}return!1}function Oe(e,t){let n=ie(e,t);return n?n.isValueReference!==!1:t.parent?.type==="VariableDeclarator"&&t.parent.init===t}function oe(e){if(e?.type==="Identifier"&&e.name)return{root:e,segments:[e.name]};if(!e||!(e.type==="MemberExpression"||!!(e.object&&e.property))||e.computed===!0)return;let n=oe(e.object),i=T(e.property);if(!(!n||!i))return{root:n.root,segments:[...n.segments,i]}}function $e(e){return T(e.callee?.property)}function se(e,t){return e?.properties?.find(n=>T(n.key)===t)}function C(e,t){return se(e,t)!==void 0}function Pe(e){let t=se(e,"metadata")?.value;return C(t,"source")}function ae(e){return $e(e)==="publish"}var le={meta:{type:"problem",docs:{description:"Disallow imports that violate ark.config.json layer rules (same contract as arkgate-check)."},messages:{forbiddenImport:"Architecture: {{fromLayer}} must not import {{toLayer}} (ark.config.json). Specifier: {{specifier}}",forbiddenImportHeuristic:"Domain code must not import infrastructure, adapters, repositories, or database modules."},schema:[]},create(e){let t=N(e),n=D(t),i=n?G(n):null,r=n?c.default.dirname(n):null,o=s=>{let a=w(s.source);if(a&&i&&r&&t){let f=c.default.isAbsolute(t)?t:c.default.resolve(t),g=c.default.relative(r,f).split(c.default.sep).join("/"),l=S(g,i.layers);if(!l)return;let u=re(f,a);if(!u)return;let d=c.default.relative(r,u).split(c.default.sep).join("/");if(d.startsWith(".."))return;let p=S(d,i.layers);if(!p)return;P(i.rules,l,p,{fromPath:g,toPath:d,layers:i.layers})&&x(e,s,"forbiddenImport",{ruleId:"LAYER_IMPORT_VIOLATION",file:g,fromLayer:l,toLayer:p,target:d,...s.importKind==="type"?{typeOnly:!0}:{},message:`${l} must not import ${p}.`},{fromLayer:l,toLayer:p,specifier:a});return}};return{ImportDeclaration:o,ExportNamedDeclaration:o,ExportAllDeclaration:o}}},ce={meta:{type:"problem",docs:{description:"Require event bus publish calls to use registered intent creators instead of raw event objects or intent strings."},messages:{rawPublish:"Publish through a registered intent creator; raw event objects or intent strings bypass Ark contracts."},schema:[]},create(e){return{CallExpression(t){let n=t.arguments?.[0],i=w(n),r=F({publishCall:ae(t),rawIntentName:i,objectHasIntent:C(n,"intent"),arkPublishCandidate:!1,hasSource:!0});if(r.some(o=>o.ruleId==="RAW_EVENT_PUBLISH")){let o=r.find(s=>s.ruleId==="RAW_EVENT_PUBLISH");x(e,t,"rawPublish",{...o,file:N(e)})}}}}},ue={meta:{type:"problem",docs:{description:"Require event bus publish calls to include source metadata."},messages:{missingSource:"Strict Ark publish calls must include metadata.source."},schema:[]},create(e){return{CallExpression(t){let n=t.arguments?.[0],i=t.arguments?.[2],o=F({publishCall:ae(t),rawIntentName:w(n),objectHasIntent:C(n,"intent"),arkPublishCandidate:!0,hasSource:Pe(n)||C(i,"source")}).find(s=>s.ruleId==="PUBLISH_MISSING_SOURCE");o&&x(e,t,"missingSource",{...o,file:N(e)})}}}},fe={meta:{type:"problem",docs:{description:"Disallow ambient globals from the layer\u2019s forbiddenGlobals in ark.config.json (same purity surface as ark-check). Option `globals` explicitly overrides."},messages:{forbiddenGlobal:'Ambient global "{{name}}" is forbidden in {{layer}} (ark.config.json); inject the capability through a port instead.',forbiddenGlobalDefault:'Ambient global "{{name}}" is forbidden here; inject the capability through a port instead.'},schema:[{type:"object",properties:{globals:{type:"array",items:{type:"string"}}},additionalProperties:!1}]},create(e){let t=N(e),n=e.options?.[0],i=D(t),r=i?G(i):null,o=i?c.default.dirname(i):null,s=null,a="this layer";if(n?.globals)s=new Set(n.globals);else if(r&&o&&t){let l=c.default.isAbsolute(t)?t:c.default.resolve(t),u=c.default.relative(o,l).split(c.default.sep).join("/"),d=r.layers?.find(p=>p.name===S(u,r.layers));d?.forbiddenGlobals?.length?(s=new Set(d.forbiddenGlobals),a=d.name):s=null}if(!s)return{};let f=typeof H(e)?.getScope=="function",g=(l,u)=>{let d=c.default.isAbsolute(t)?t:c.default.resolve(t),p=o?c.default.relative(o,d).split(c.default.sep).join("/"):t;x(e,l,r?"forbiddenGlobal":"forbiddenGlobalDefault",{ruleId:"FORBIDDEN_GLOBAL",file:p,fromLayer:a,target:u,message:`${a} must not use the ambient global "${u}".`},{name:u,layer:a})};return{MemberExpression(l){if(l.parent?.type==="MemberExpression"&&l.parent.object===l)return;let u=oe(l);if(!u||ne(e,u.root,u.segments[0]))return;let d=u.segments[0]==="globalThis",p=d?u.segments.slice(1):u.segments,L;for(let _=p.length;_>=(d?1:2);_-=1){let U=p.slice(0,_).join(".");if(s.has(U)){L=U;break}}L?g(l,L):!f&&s.has(u.segments[0])&&g(l,u.segments[0])},CallExpression(l){if(f)return;let u=l.callee?.type==="Identifier"?l.callee.name:void 0;u&&s.has(u)&&g(l,u)},NewExpression(l){if(f)return;let u=l.callee?.type==="Identifier"?l.callee.name:void 0;u&&s.has(u)&&g(l,u)},Identifier(l){!f||!l.name||!s.has(l.name)||!Oe(e,l)||ne(e,l,l.name)||g(l,l.name)}}}},je={"no-domain-infra-imports":le,"no-raw-event-publish":ce,"require-publish-source":ue,"no-forbidden-globals":fe},E={rules:je};E.configs={recommended:{plugins:{ark:E},rules:{"ark/no-domain-infra-imports":"error","ark/no-raw-event-publish":"error","ark/require-publish-source":"error","ark/no-forbidden-globals":"error"}}};var Ve=E;0&&(module.exports={findConfigPath,globToRegExp,isEdgeDenied,layerForRelativePath,loadArkConfig,noDomainInfraImports,noForbiddenGlobals,noRawEventPublish,patternSpecificity,plugin,requirePublishSource,resolveRelativeImport});
3
+ `)}`),this.name="ArkConfigValidationError",this.source=t,this.issues=n}};function ne(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}function D(e,t){return/^[A-Za-z_$][A-Za-z0-9_$]*$/.test(t)?`${e}.${t}`:`${e}[${JSON.stringify(t)}]`}function A(e){return e===null?"null":Array.isArray(e)?"array":typeof e}function Oe(e,t){let n="#/$defs/";if(e.startsWith(n))return t.$defs[e.slice(n.length)]}function x(e,t,n,i,r){if(t.$ref){let s=Oe(t.$ref,i);if(!s){r.push({path:n,message:`schema reference ${t.$ref} cannot be resolved`});return}x(e,s,n,i,r);return}if(t.const!==void 0&&!Object.is(e,t.const)){r.push({path:n,message:`must equal ${JSON.stringify(t.const)}`});return}if(t.enum&&!t.enum.some(s=>Object.is(s,e))){r.push({path:n,message:`must be one of ${t.enum.map(String).join(", ")}`});return}if(t.type==="object"){if(!ne(e)){r.push({path:n,message:`must be an object; received ${A(e)}`});return}let s=t.properties??{};for(let l of t.required??[])e[l]===void 0&&r.push({path:D(n,l),message:"is required"});if(t.additionalProperties===!1)for(let l of Object.keys(e))l in s||r.push({path:D(n,l),message:"unknown field"});for(let[l,c]of Object.entries(s))e[l]!==void 0&&x(e[l],c,D(n,l),i,r);return}if(t.type==="array"){if(!Array.isArray(e)){r.push({path:n,message:`must be an array; received ${A(e)}`});return}if(t.minItems!==void 0&&e.length<t.minItems&&r.push({path:n,message:`must contain at least ${t.minItems} item(s)`}),t.uniqueItems){let s=e.map(l=>JSON.stringify(l));new Set(s).size!==s.length&&r.push({path:n,message:"must not contain duplicate items"})}t.items&&e.forEach((s,l)=>x(s,t.items,`${n}[${l}]`,i,r));return}if(t.type==="string"){if(typeof e!="string"){r.push({path:n,message:`must be a string; received ${A(e)}`});return}t.minLength!==void 0&&e.length<t.minLength&&r.push({path:n,message:`must contain at least ${t.minLength} character(s)`});return}if(t.type==="boolean"){typeof e!="boolean"&&r.push({path:n,message:`must be a boolean; received ${A(e)}`});return}if(t.type==="integer"){if(!Number.isInteger(e)){r.push({path:n,message:`must be an integer; received ${A(e)}`});return}t.minimum!==void 0&&e<t.minimum&&r.push({path:n,message:`must be at least ${t.minimum}`})}}function $e(e){return{...e,$schema:e.$schema===void 0?M:e.$schema,schemaVersion:e.schemaVersion===void 0?"1.0":e.schemaVersion,include:e.include===void 0?["src"]:e.include,layers:e.layers===void 0?[]:e.layers,rules:e.rules===void 0?te.map(t=>({...t})):e.rules}}function Pe(e,t="ark.config.json"){if(!ne(e))throw new k(t,[{path:"$",message:`must be an object; received ${A(e)}`}]);let n=e.schemaVersion===void 0?"unversioned":null;if(e.schemaVersion!==void 0&&e.schemaVersion!=="1.0")throw new k(t,[{path:"$.schemaVersion",message:`unsupported version ${JSON.stringify(e.schemaVersion)}; expected 1.0`}]);return{candidate:$e(e),migratedFrom:n}}function je(e,t="ark.config.json"){let{candidate:n,migratedFrom:i}=Pe(e,t),r=[];if(x(n,ee,"$",ee,r),r.length>0)throw new k(t,r);return{config:n,migratedFrom:i}}function re(e,t="ark.config.json"){let n;try{n=JSON.parse(e)}catch(i){throw new k(t,[{path:"$",message:`invalid JSON: ${i instanceof Error?i.message:String(i)}`}])}return je(n,t)}function m(e){return typeof e=="string"&&e.length>0?e:void 0}function ie(e,t){return Number.isInteger(e)&&Number(e)>0?Number(e):t}function Fe(e,t,n){return e==="LAYER_IMPORT_VIOLATION"?t.typeOnly||n.targetTypeOnlyExports===!0||n.namedBindingsTypeOnly===!0?"Move the referenced type to a mutually allowed layer, use `import type`, then preflight again.":n.peerIsolation===!0?"Extract the shared dependency to a shared layer, then preflight again.":`Define a port in ${t.fromLayer??"the source layer"}, inject the ${t.toLayer??"outer-layer"} implementation, then preflight again.`:e==="FORBIDDEN_GLOBAL"?`Inject ${t.target??"the capability"} through a port, then preflight again.`:e==="CAPABILITY_VIOLATION"?`Define a ${m(n.capability)??"capability"} port in ${t.fromLayer??"the walled layer"}, bind the implementation outside it, then preflight again.`:e==="CIRCULAR_DEPENDENCY"?"Extract the shared dependency into a third module, then preflight again.":e==="RAW_EVENT_PUBLISH"?"Publish through a registered intent creator, then run Ark again.":e==="PUBLISH_MISSING_SOURCE"?"Add metadata.source to the publish call, then run Ark again.":`Resolve ${e} without weakening ark.config.json, then run Ark again.`}function se(e,t="error"){let n=m(e.ruleId)??m(e.code)??"ARK_UNKNOWN",i=e.severity==="warning"?"warning":t,r={...m(e.target)?{target:m(e.target)}:{},...m(e.fromLayer)?{fromLayer:m(e.fromLayer)}:{},...m(e.toLayer)?{toLayer:m(e.toLayer)}:{},...typeof e.typeOnly=="boolean"?{typeOnly:e.typeOnly}:{}};return{ruleId:n,severity:i,message:m(e.message)??n,location:{file:m(e.file)??"<unknown>",line:ie(e.line,1),column:ie(e.column,1)},evidence:r,nextAction:m(e.nextAction)??Fe(n,r,e)}}var oe={RAW_EVENT_PUBLISH:"Publish through a registered intent creator; raw event objects or intent strings bypass Ark contracts and tooling.",PUBLISH_MISSING_SOURCE:"Strict Ark publish calls must include metadata.source."};function Ve(e){return/^(Domain|Application|Adapter|Workflow|Job|Presentation|Reporting|Metadata|Security|Audit|Observability|Kernel)\.[A-Za-z0-9_.]+$/.test(e)}function T(e){if(!e.publishCall)return[];let t=[];return(e.rawIntentName!==void 0&&Ve(e.rawIntentName)||e.objectHasIntent)&&t.push({ruleId:"RAW_EVENT_PUBLISH",message:oe.RAW_EVENT_PUBLISH}),e.arkPublishCandidate&&!e.hasSource&&t.push({ruleId:"PUBLISH_MISSING_SOURCE",message:oe.PUBLISH_MISSING_SOURCE}),t}function I(e){if(typeof e.physicalFilename=="string"&&e.physicalFilename.length>0)return e.physicalFilename;if(typeof e.filename=="string"&&e.filename.length>0)return e.filename;if(typeof e.getFilename=="function")try{let t=e.getFilename();if(typeof t=="string"&&t.length>0)return t}catch{}return""}function w(e,t,n,i,r){let s=se({...i,line:i.line??t.loc?.start?.line,column:i.column??(typeof t.loc?.start?.column=="number"?t.loc.start.column+1:void 0)});return e.report({node:t,messageId:n,...r?{data:r}:{},diagnostic:s}),s}function L(e){if(!e||e==="<input>"||e.startsWith("stdin"))return null;let t=u.default.dirname(u.default.resolve(e));for(;;){let n=u.default.join(t,"ark.config.json");if(S.default.existsSync(n))return n;let i=u.default.dirname(t);if(i===t)return null;t=i}}var v=new Map;function _(e){if(v.has(e))return v.get(e)??null;if(!S.default.existsSync(e))return null;let t=re(S.default.readFileSync(e,"utf8"),e).config;return v.set(e,t),t}function ae(e,t){if(!t.startsWith("."))return null;let n=u.default.resolve(u.default.dirname(e),t),i=[n,`${n}.ts`,`${n}.tsx`,`${n}.mts`,`${n}.cts`,`${n}.js`,`${n}.jsx`,u.default.join(n,"index.ts"),u.default.join(n,"index.tsx"),u.default.join(n,"index.js")];for(let r of i)try{if(S.default.existsSync(r)&&S.default.statSync(r).isFile())return r}catch{}return`${n}.ts`}function O(e){return typeof e?.value=="string"?e.value:void 0}function B(e){return e?.name??O(e)}function H(e){return e.sourceCode??e.getSourceCode?.()}function le(e,t){let n=H(e)?.getScope?.(t);for(;n;){let i=n.references?.find(r=>r.identifier===t);if(i)return i;n=n.upper??void 0}}function G(e,t,n){let i=le(e,t);if(i?.resolved)return(i.resolved.defs?.length??0)>0;let r=H(e)?.getScope?.(t);for(;r;){let s=r.set?.get(n);if(s)return(s.defs?.length??0)>0;r=r.upper??void 0}return!1}function De(e,t){let n=le(e,t);return n?n.isValueReference!==!1:t.parent?.type==="VariableDeclarator"&&t.parent.init===t}function ce(e){if(e?.type==="Identifier"&&e.name)return{root:e,segments:[e.name]};if(!e||!(e.type==="MemberExpression"||!!(e.object&&e.property))||e.computed===!0)return;let n=ce(e.object),i=B(e.property);if(!(!n||!i))return{root:n.root,segments:[...n.segments,i]}}function Me(e){return B(e.callee?.property)}function ue(e,t){return e?.properties?.find(n=>B(n.key)===t)}function E(e,t){return ue(e,t)!==void 0}function Te(e){let t=ue(e,"metadata")?.value;return E(t,"source")}function de(e){return Me(e)==="publish"}var fe={meta:{type:"problem",docs:{description:"Disallow imports that violate ark.config.json layer rules (same contract as arkgate-check)."},messages:{forbiddenImport:"Architecture: {{fromLayer}} must not import {{toLayer}} (ark.config.json). Specifier: {{specifier}}",forbiddenImportHeuristic:"Domain code must not import infrastructure, adapters, repositories, or database modules."},schema:[]},create(e){let t=I(e),n=L(t),i=n?_(n):null,r=n?u.default.dirname(n):null,s=l=>{let c=O(l.source);if(c&&i&&r&&t){let p=u.default.isAbsolute(t)?t:u.default.resolve(t),g=u.default.relative(r,p).split(u.default.sep).join("/"),o=h(g,i.layers);if(!o)return;let a=ae(p,c);if(!a)return;let d=u.default.relative(r,a).split(u.default.sep).join("/");if(d.startsWith(".."))return;let f=h(d,i.layers);if(!f)return;F(i.rules,o,f,{fromPath:g,toPath:d,layers:i.layers})&&w(e,l,"forbiddenImport",{ruleId:"LAYER_IMPORT_VIOLATION",file:g,fromLayer:o,toLayer:f,target:d,...l.importKind==="type"?{typeOnly:!0}:{},message:`${o} must not import ${f}.`},{fromLayer:o,toLayer:f,specifier:c});return}};return{ImportDeclaration:s,ExportNamedDeclaration:s,ExportAllDeclaration:s}}},pe={meta:{type:"problem",docs:{description:"Require event bus publish calls to use registered intent creators instead of raw event objects or intent strings."},messages:{rawPublish:"Publish through a registered intent creator; raw event objects or intent strings bypass Ark contracts."},schema:[]},create(e){return{CallExpression(t){let n=t.arguments?.[0],i=O(n),r=T({publishCall:de(t),rawIntentName:i,objectHasIntent:E(n,"intent"),arkPublishCandidate:!1,hasSource:!0});if(r.some(s=>s.ruleId==="RAW_EVENT_PUBLISH")){let s=r.find(l=>l.ruleId==="RAW_EVENT_PUBLISH");w(e,t,"rawPublish",{...s,file:I(e)})}}}}},ge={meta:{type:"problem",docs:{description:"Require event bus publish calls to include source metadata."},messages:{missingSource:"Strict Ark publish calls must include metadata.source."},schema:[]},create(e){return{CallExpression(t){let n=t.arguments?.[0],i=t.arguments?.[2],s=T({publishCall:de(t),rawIntentName:O(n),objectHasIntent:E(n,"intent"),arkPublishCandidate:!0,hasSource:Te(n)||E(i,"source")}).find(l=>l.ruleId==="PUBLISH_MISSING_SOURCE");s&&w(e,t,"missingSource",{...s,file:I(e)})}}}},me={meta:{type:"problem",docs:{description:"Disallow ambient globals from the layer\u2019s forbiddenGlobals in ark.config.json (same purity surface as ark-check). Option `globals` explicitly overrides."},messages:{forbiddenGlobal:'Ambient global "{{name}}" is forbidden in {{layer}} (ark.config.json); inject the capability through a port instead.',forbiddenGlobalDefault:'Ambient global "{{name}}" is forbidden here; inject the capability through a port instead.'},schema:[{type:"object",properties:{globals:{type:"array",items:{type:"string"}}},additionalProperties:!1}]},create(e){let t=I(e),n=e.options?.[0],i=L(t),r=i?_(i):null,s=i?u.default.dirname(i):null,l=null,c="this layer";if(n?.globals)l=new Set(n.globals);else if(r&&s&&t){let o=u.default.isAbsolute(t)?t:u.default.resolve(t),a=u.default.relative(s,o).split(u.default.sep).join("/"),d=r.layers?.find(f=>f.name===h(a,r.layers));d?.forbiddenGlobals?.length?(l=new Set(d.forbiddenGlobals),c=d.name):l=null}if(!l)return{};let p=typeof H(e)?.getScope=="function",g=(o,a)=>{let d=u.default.isAbsolute(t)?t:u.default.resolve(t),f=s?u.default.relative(s,d).split(u.default.sep).join("/"):t;w(e,o,r?"forbiddenGlobal":"forbiddenGlobalDefault",{ruleId:"FORBIDDEN_GLOBAL",file:f,fromLayer:c,target:a,message:`${c} must not use the ambient global "${a}".`},{name:a,layer:c})};return{MemberExpression(o){if(o.parent?.type==="MemberExpression"&&o.parent.object===o)return;let a=ce(o);if(!a||G(e,a.root,a.segments[0]))return;let d=a.segments[0]==="globalThis",f=d?a.segments.slice(1):a.segments,y;for(let $=f.length;$>=(d?1:2);$-=1){let K=f.slice(0,$).join(".");if(l.has(K)){y=K;break}}y?g(o,y):!p&&l.has(a.segments[0])&&g(o,a.segments[0])},CallExpression(o){if(p)return;let a=o.callee?.type==="Identifier"?o.callee.name:void 0;a&&l.has(a)&&g(o,a)},NewExpression(o){if(p)return;let a=o.callee?.type==="Identifier"?o.callee.name:void 0;a&&l.has(a)&&g(o,a)},Identifier(o){!p||!o.name||!l.has(o.name)||!De(e,o)||G(e,o,o.name)||g(o,o.name)}}}},ye={meta:{type:"problem",docs:{description:"Disallow importing modules whose effect capability the layer denies (ark.config.json capabilities.deny / pure \u2014 same wall surface as ark-check). Import dimension only: ambient globals stay with no-forbidden-globals and the CLI/hook symbol path."},messages:{deniedCapability:'{{layer}} denies the {{capability}} capability (ark.config.json); "{{specifier}}" imports it. Define a port and bind the implementation in an adapter layer.'},schema:[]},create(e){let t=I(e),n=L(t),i=n?_(n):null,r=n?u.default.dirname(n):null;if(!i||!r||!t)return{};let s=u.default.isAbsolute(t)?t:u.default.resolve(t),l=u.default.relative(r,s).split(u.default.sep).join("/"),c=i.layers?.find(o=>o.name===h(l,i.layers));if(!c)return{};let p=new Set(X(c));if(p.size===0)return{};let g=(o,a,d)=>{if(d||typeof a!="string")return;let f=Z(a);!f||!p.has(f)||w(e,o,"deniedCapability",{ruleId:"CAPABILITY_VIOLATION",file:l,fromLayer:c.name,target:a,capability:f,message:`${c.name} denies the ${f} capability; found import of "${a}".`},{layer:c.name,capability:f,specifier:a})};return{ImportDeclaration(o){let a=o,d=(a.specifiers??[]).filter(y=>y.type==="ImportSpecifier"),f=d.length>0&&d.length===(a.specifiers??[]).length&&d.every(y=>y.importKind==="type");g(o,a.source?.value,a.importKind==="type"||f)},ImportExpression(o){let a=o;a.source?.type==="Literal"&&g(o,a.source.value,!1)},ExportNamedDeclaration(o){let a=o;if(!a.source)return;let d=a.specifiers??[],f=d.length>0&&d.every(y=>y.exportKind==="type");g(o,a.source.value,a.exportKind==="type"||f)},ExportAllDeclaration(o){let a=o;g(o,a.source?.value,a.exportKind==="type")},CallExpression(o){let a=o;a.callee?.type==="Identifier"&&a.callee.name==="require"&&a.arguments?.[0]?.type==="Literal"&&!G(e,o,"require")&&g(o,a.arguments[0].value,!1)}}}},ve={"no-domain-infra-imports":fe,"no-raw-event-publish":pe,"require-publish-source":ge,"no-forbidden-globals":me,"no-denied-capabilities":ye},N={rules:ve};N.configs={recommended:{plugins:{ark:N},rules:{"ark/no-domain-infra-imports":"error","ark/no-raw-event-publish":"error","ark/require-publish-source":"error","ark/no-forbidden-globals":"error","ark/no-denied-capabilities":"error"}}};var Ge=N;0&&(module.exports={findConfigPath,globToRegExp,isEdgeDenied,layerForRelativePath,loadArkConfig,noDeniedCapabilities,noDomainInfraImports,noForbiddenGlobals,noRawEventPublish,patternSpecificity,plugin,requirePublishSource,resolveRelativeImport});
@@ -1,4 +1,4 @@
1
- import { A as ArkConfig } from '../configTypes-CVWWhBoe.cjs';
1
+ import { A as ArkConfig } from '../configTypes-DAPvBqK6.cjs';
2
2
 
3
3
  /**
4
4
  * Pure layer-glob matching for ark.config.json.
@@ -138,8 +138,9 @@ declare const noDomainInfraImports: ArkRule;
138
138
  declare const noRawEventPublish: ArkRule;
139
139
  declare const requirePublishSource: ArkRule;
140
140
  declare const noForbiddenGlobals: ArkRule;
141
+ declare const noDeniedCapabilities: ArkRule;
141
142
  declare const plugin: ArkEslintPlugin;
142
143
 
143
144
  // @ts-ignore
144
145
  export = plugin;
145
- export { findConfigPath, globToRegExp, isEdgeDenied, layerForRelativePath, loadArkConfig, noDomainInfraImports, noForbiddenGlobals, noRawEventPublish, patternSpecificity, plugin, requirePublishSource, resolveRelativeImport };
146
+ export { findConfigPath, globToRegExp, isEdgeDenied, layerForRelativePath, loadArkConfig, noDeniedCapabilities, noDomainInfraImports, noForbiddenGlobals, noRawEventPublish, patternSpecificity, plugin, requirePublishSource, resolveRelativeImport };
@@ -1,4 +1,4 @@
1
- import { A as ArkConfig } from '../configTypes-CVWWhBoe.js';
1
+ import { A as ArkConfig } from '../configTypes-DAPvBqK6.js';
2
2
 
3
3
  /**
4
4
  * Pure layer-glob matching for ark.config.json.
@@ -138,6 +138,7 @@ declare const noDomainInfraImports: ArkRule;
138
138
  declare const noRawEventPublish: ArkRule;
139
139
  declare const requirePublishSource: ArkRule;
140
140
  declare const noForbiddenGlobals: ArkRule;
141
+ declare const noDeniedCapabilities: ArkRule;
141
142
  declare const plugin: ArkEslintPlugin;
142
143
 
143
- export { plugin as default, findConfigPath, globToRegExp, isEdgeDenied, layerForRelativePath, loadArkConfig, noDomainInfraImports, noForbiddenGlobals, noRawEventPublish, patternSpecificity, plugin, requirePublishSource, resolveRelativeImport };
144
+ export { plugin as default, findConfigPath, globToRegExp, isEdgeDenied, layerForRelativePath, loadArkConfig, noDeniedCapabilities, noDomainInfraImports, noForbiddenGlobals, noRawEventPublish, patternSpecificity, plugin, requirePublishSource, resolveRelativeImport };
@@ -1,3 +1,3 @@
1
- import b from"fs";import u from"path";var D=new Map;function G(e){return/[.*+?^${}()|[\]\\]/.test(e)?`\\${e}`:e}function L(e){let t="";for(let n=0;n<e.length;n+=1){let i=e[n];if(i==="\\"&&n+1<e.length){let r=e[n+1];if("*?{}[],".includes(r)||r==="\\"){t+="\\"+r,n+=1;continue}t+="/";continue}t+=i}return t}function ie(e){let t=0;for(let n=0;n<e.length;n+=1){let i=e[n];if(i==="\\"){n+=1;continue}if(i==="{")t+=1;else if(i==="}"&&(t-=1,t<0))return!1}return t===0}function w(e){let t=D.get(e);if(t)return t;let n=L(e),i=ie(n),r="",o=0;for(let a=0;a<n.length;a+=1){let f=n[a];f==="\\"&&a+1<n.length?(r+=G(n[a+1]),a+=1):f==="*"?n[a+1]==="*"?n[a+2]==="/"?(r+="(?:.*/)?",a+=2):(r+=".*",a+=1):r+="[^/]*":f==="?"?r+="[^/]":f==="{"&&i?(r+="(?:",o+=1):f==="}"&&i&&o>0?(r+=")",o-=1):f===","&&i&&o>0?r+="|":r+=G(f)}let s=new RegExp(`^${r}$`);return D.set(e,s),s}function H(e){let t=L(String(e)),i=t.split("*")[0].split("/").filter(Boolean).length,r=t.replace(/\*/g,"").length;return i*1e4+r}function S(e,t){let n=String(e).split(/[/\\]/).join("/"),i,r=-1;for(let o of t??[])if(!(o.exclude??[]).some(s=>w(s).test(n))){for(let s of o.patterns??[])if(w(s).test(n)){let a=H(s);a>r&&(r=a,i=o.name)}}return i}function T(e,t){if(!t?.length)return;let n=String(e).split(/[/\\]/).filter(Boolean),i=new Set(t.map(r=>String(r).toLowerCase()));for(let r=0;r<n.length-1;r+=1)if(i.has(n[r].toLowerCase()))return`${n[r]}/${n[r+1]}`}function oe(e){let t=new Set;for(let n of e??[]){let r=L(String(n)).split("/").filter(Boolean);for(let o=0;o<r.length;o+=1){let s=r[o];if((s==="**"||s==="*")&&o>0){let a=r[o-1];a&&!a.includes("*")&&!a.includes("{")&&!a.includes("}")&&t.add(a)}}}return[...t]}function se(e,t,n){if(Array.isArray(e.sliceFolders)&&e.sliceFolders.length>0)return e.sliceFolders.filter(r=>typeof r=="string"&&r.length>0);let i=(n??[]).find(r=>r.name===t);return oe(i?.patterns)}function ae(e,t,n,i){for(let r of e??[])if(!(r.from!==t||r.to!==n)&&r.allowed===!1){if(r.peerIsolation){let o=i?.fromPath,s=i?.toPath;if(!o||!s)continue;let a=se(r,t,i?.layers);if(a.length===0)continue;let f=T(o,a),g=T(s,a);if(!f||!g)continue;if(f!==g)return r;continue}if(t!==n)return r}}function U(e,t,n,i){return ae(e,t,n,i)!==void 0}var O="https://unpkg.com/arkgate@2/schemas/ark.config.schema.json",v=["DomainModel","ApplicationOrchestration","PersistenceAdapters","IntegrationAdapters","WorkflowSagaEngine","BackgroundJobsScheduling","PresentationAdapters","ReportingReadModels","ExtensibilityMetadata","SecurityAuditObservability","Kernel"],le=new Set(["PresentationAdapters->ApplicationOrchestration","ApplicationOrchestration->DomainModel","WorkflowSagaEngine->ApplicationOrchestration","WorkflowSagaEngine->DomainModel","BackgroundJobsScheduling->ApplicationOrchestration"]);function ce(){let e=[];for(let t of v)for(let n of v)t===n||le.has(`${t}->${n}`)||e.push({from:t,to:n,allowed:!1});return e}var K=ce();var y={type:"array",items:{type:"string",minLength:1},uniqueItems:!0},B={$schema:"https://json-schema.org/draft/2020-12/schema",$id:O,title:"ArkGate architecture contract",description:"Versioned contract consumed identically by ArkGate CLI, MCP, and ESLint surfaces.",type:"object",additionalProperties:!1,required:["$schema","schemaVersion","include","layers","rules"],properties:{$schema:{type:"string",minLength:1,default:O,description:"Editor-facing URL or local path for this JSON Schema."},schemaVersion:{type:"string",const:"1.0",default:"1.0"},name:{type:"string",minLength:1},include:{...y,minItems:1,default:["src"]},exclude:{...y,default:[]},excludeGenerated:{type:"boolean",default:!0},frameworkOverlay:{type:"string",minLength:1},layers:{type:"array",default:[],items:{$ref:"#/$defs/layer"}},rules:{type:"array",default:K,items:{$ref:"#/$defs/rule"}},cyclePolicy:{type:"string",enum:["strict","soft","framework-soft","off"],default:"strict"},dynamicImportAllowlist:{...y,default:[]},safety:{$ref:"#/$defs/safety",default:{maxTsSuppressions:0,maxAnyCasts:0,allowInMemory:!1,allowDisabledPeerIsolation:!1}}},$defs:{layer:{type:"object",additionalProperties:!1,required:["name","patterns"],properties:{name:{type:"string",minLength:1},patterns:{...y,minItems:1},exclude:y,intentPrefixes:y,description:{type:"string",minLength:1},forbiddenGlobals:y,mayImportInfrastructure:{type:"boolean"},optional:{type:"boolean"}}},rule:{type:"object",additionalProperties:!1,required:["from","to","allowed"],properties:{from:{type:"string",minLength:1},to:{type:"string",minLength:1},allowed:{type:"boolean"},message:{type:"string",minLength:1},peerIsolation:{type:"boolean"},sliceFolders:{...y,minItems:1}}},safety:{type:"object",additionalProperties:!1,properties:{maxTsSuppressions:{type:"integer",minimum:0,default:0},maxAnyCasts:{type:"integer",minimum:0,default:0},allowInMemory:{type:"boolean",default:!1},allowDisabledPeerIsolation:{type:"boolean",default:!1}}}}},A=class extends Error{issues;source;constructor(t,n){super(`Invalid ArkGate config (${t}):
1
+ import S from"fs";import u from"path";var B=new Map;function H(e){return/[.*+?^${}()|[\]\\]/.test(e)?`\\${e}`:e}function L(e){let t="";for(let n=0;n<e.length;n+=1){let i=e[n];if(i==="\\"&&n+1<e.length){let r=e[n+1];if("*?{}[],".includes(r)||r==="\\"){t+="\\"+r,n+=1;continue}t+="/";continue}t+=i}return t}function le(e){let t=0;for(let n=0;n<e.length;n+=1){let i=e[n];if(i==="\\"){n+=1;continue}if(i==="{")t+=1;else if(i==="}"&&(t-=1,t<0))return!1}return t===0}function N(e){let t=B.get(e);if(t)return t;let n=L(e),i=le(n),r="",s=0;for(let c=0;c<n.length;c+=1){let p=n[c];p==="\\"&&c+1<n.length?(r+=H(n[c+1]),c+=1):p==="*"?n[c+1]==="*"?n[c+2]==="/"?(r+="(?:.*/)?",c+=2):(r+=".*",c+=1):r+="[^/]*":p==="?"?r+="[^/]":p==="{"&&i?(r+="(?:",s+=1):p==="}"&&i&&s>0?(r+=")",s-=1):p===","&&i&&s>0?r+="|":r+=H(p)}let l=new RegExp(`^${r}$`);return B.set(e,l),l}function U(e){let t=L(String(e)),i=t.split("*")[0].split("/").filter(Boolean).length,r=t.replace(/\*/g,"").length;return i*1e4+r}function k(e,t){let n=String(e).split(/[/\\]/).join("/"),i,r=-1;for(let s of t??[])if(!(s.exclude??[]).some(l=>N(l).test(n))){for(let l of s.patterns??[])if(N(l).test(n)){let c=U(l);c>r&&(r=c,i=s.name)}}return i}function K(e,t){if(!t?.length)return;let n=String(e).split(/[/\\]/).filter(Boolean),i=new Set(t.map(r=>String(r).toLowerCase()));for(let r=0;r<n.length-1;r+=1)if(i.has(n[r].toLowerCase()))return`${n[r]}/${n[r+1]}`}function ce(e){let t=new Set;for(let n of e??[]){let r=L(String(n)).split("/").filter(Boolean);for(let s=0;s<r.length;s+=1){let l=r[s];if((l==="**"||l==="*")&&s>0){let c=r[s-1];c&&!c.includes("*")&&!c.includes("{")&&!c.includes("}")&&t.add(c)}}}return[...t]}function ue(e,t,n){if(Array.isArray(e.sliceFolders)&&e.sliceFolders.length>0)return e.sliceFolders.filter(r=>typeof r=="string"&&r.length>0);let i=(n??[]).find(r=>r.name===t);return ce(i?.patterns)}function de(e,t,n,i){for(let r of e??[])if(!(r.from!==t||r.to!==n)&&r.allowed===!1){if(r.peerIsolation){let s=i?.fromPath,l=i?.toPath;if(!s||!l)continue;let c=ue(r,t,i?.layers);if(c.length===0)continue;let p=K(s,c),g=K(l,c);if(!p||!g)continue;if(p!==g)return r;continue}if(t!==n)return r}}function q(e,t,n,i){return de(e,t,n,i)!==void 0}var W=Object.freeze(["network","filesystem","clock","randomness","environment","process","persistence"]),fe=Object.freeze({fetch:"network",XMLHttpRequest:"network",Date:"clock","Date.now":"clock","Math.random":"randomness","process.env":"environment",process:"process"}),$e=Object.freeze(Object.keys(fe).sort()),_=Object.freeze({fs:"filesystem","node:fs":"filesystem","fs/promises":"filesystem","node:fs/promises":"filesystem","fs-extra":"filesystem","graceful-fs":"filesystem",memfs:"filesystem",chokidar:"filesystem",http:"network",https:"network",http2:"network",net:"network",tls:"network",dgram:"network",dns:"network","node:http":"network","node:https":"network","node:http2":"network","node:net":"network","node:tls":"network","node:dgram":"network","node:dns":"network",axios:"network",undici:"network","node-fetch":"network",got:"network",ky:"network",superagent:"network",ws:"network",process:"process","node:process":"process",child_process:"process","node:child_process":"process","@prisma/client":"persistence",prisma:"persistence",pg:"persistence",mysql:"persistence",mysql2:"persistence",mongodb:"persistence",mongoose:"persistence",sqlite3:"persistence","better-sqlite3":"persistence",redis:"persistence",ioredis:"persistence",typeorm:"persistence",knex:"persistence","drizzle-orm":"persistence",sequelize:"persistence",kysely:"persistence","@supabase/supabase-js":"persistence"});function Y(e){if(!e||e.startsWith(".")||e.startsWith("/"))return null;let t=_[e];if(t)return t;let n=e.indexOf("/");if(n<0)return null;let i=e.slice(0,n),r=_[i];if(r)return r;let s=e.indexOf("/",n+1);return s<0?null:_[e.slice(0,s)]??null}function z(e){if(e?.pure===!0)return[...W].sort();let n=(e?.capabilities?.deny??[]).filter(i=>W.includes(i));return[...new Set(n)].sort()}var $="https://unpkg.com/arkgate@2/schemas/ark.config.schema.json",J=["DomainModel","ApplicationOrchestration","PersistenceAdapters","IntegrationAdapters","WorkflowSagaEngine","BackgroundJobsScheduling","PresentationAdapters","ReportingReadModels","ExtensibilityMetadata","SecurityAuditObservability","Kernel"],pe=new Set(["PresentationAdapters->ApplicationOrchestration","ApplicationOrchestration->DomainModel","WorkflowSagaEngine->ApplicationOrchestration","WorkflowSagaEngine->DomainModel","BackgroundJobsScheduling->ApplicationOrchestration"]);function ge(){let e=[];for(let t of J)for(let n of J)t===n||pe.has(`${t}->${n}`)||e.push({from:t,to:n,allowed:!1});return e}var X=ge();var b={type:"array",items:{type:"string",minLength:1},uniqueItems:!0},Z={$schema:"https://json-schema.org/draft/2020-12/schema",$id:$,title:"ArkGate architecture contract",description:"Versioned contract consumed identically by ArkGate CLI, MCP, and ESLint surfaces.",type:"object",additionalProperties:!1,required:["$schema","schemaVersion","include","layers","rules"],properties:{$schema:{type:"string",minLength:1,default:$,description:"Editor-facing URL or local path for this JSON Schema."},schemaVersion:{type:"string",const:"1.0",default:"1.0"},name:{type:"string",minLength:1},include:{...b,minItems:1,default:["src"]},exclude:{...b,default:[]},excludeGenerated:{type:"boolean",default:!0},frameworkOverlay:{type:"string",minLength:1},layers:{type:"array",default:[],items:{$ref:"#/$defs/layer"}},rules:{type:"array",default:X,items:{$ref:"#/$defs/rule"}},cyclePolicy:{type:"string",enum:["strict","soft","framework-soft","off"],default:"strict"},dynamicImportAllowlist:{...b,default:[]},safety:{$ref:"#/$defs/safety",default:{maxTsSuppressions:0,maxAnyCasts:0,allowInMemory:!1,allowDisabledPeerIsolation:!1}}},$defs:{layer:{type:"object",additionalProperties:!1,required:["name","patterns"],properties:{name:{type:"string",minLength:1},patterns:{...b,minItems:1},exclude:b,intentPrefixes:b,description:{type:"string",minLength:1},forbiddenGlobals:b,capabilities:{type:"object",additionalProperties:!1,properties:{deny:{type:"array",uniqueItems:!0,items:{type:"string",enum:["network","filesystem","clock","randomness","environment","process","persistence"]}}}},pure:{type:"boolean"},mayImportInfrastructure:{type:"boolean"},optional:{type:"boolean"}}},rule:{type:"object",additionalProperties:!1,required:["from","to","allowed"],properties:{from:{type:"string",minLength:1},to:{type:"string",minLength:1},allowed:{type:"boolean"},message:{type:"string",minLength:1},peerIsolation:{type:"boolean"},sliceFolders:{...b,minItems:1}}},safety:{type:"object",additionalProperties:!1,properties:{maxTsSuppressions:{type:"integer",minimum:0,default:0},maxAnyCasts:{type:"integer",minimum:0,default:0},allowInMemory:{type:"boolean",default:!1},allowDisabledPeerIsolation:{type:"boolean",default:!1}}}}},A=class extends Error{issues;source;constructor(t,n){super(`Invalid ArkGate config (${t}):
2
2
  ${n.map(i=>`- ${i.path}: ${i.message}`).join(`
3
- `)}`),this.name="ArkConfigValidationError",this.source=t,this.issues=n}};function W(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}function _(e,t){return/^[A-Za-z_$][A-Za-z0-9_$]*$/.test(t)?`${e}.${t}`:`${e}[${JSON.stringify(t)}]`}function h(e){return e===null?"null":Array.isArray(e)?"array":typeof e}function ue(e,t){let n="#/$defs/";if(e.startsWith(n))return t.$defs[e.slice(n.length)]}function k(e,t,n,i,r){if(t.$ref){let o=ue(t.$ref,i);if(!o){r.push({path:n,message:`schema reference ${t.$ref} cannot be resolved`});return}k(e,o,n,i,r);return}if(t.const!==void 0&&!Object.is(e,t.const)){r.push({path:n,message:`must equal ${JSON.stringify(t.const)}`});return}if(t.enum&&!t.enum.some(o=>Object.is(o,e))){r.push({path:n,message:`must be one of ${t.enum.map(String).join(", ")}`});return}if(t.type==="object"){if(!W(e)){r.push({path:n,message:`must be an object; received ${h(e)}`});return}let o=t.properties??{};for(let s of t.required??[])e[s]===void 0&&r.push({path:_(n,s),message:"is required"});if(t.additionalProperties===!1)for(let s of Object.keys(e))s in o||r.push({path:_(n,s),message:"unknown field"});for(let[s,a]of Object.entries(o))e[s]!==void 0&&k(e[s],a,_(n,s),i,r);return}if(t.type==="array"){if(!Array.isArray(e)){r.push({path:n,message:`must be an array; received ${h(e)}`});return}if(t.minItems!==void 0&&e.length<t.minItems&&r.push({path:n,message:`must contain at least ${t.minItems} item(s)`}),t.uniqueItems){let o=e.map(s=>JSON.stringify(s));new Set(o).size!==o.length&&r.push({path:n,message:"must not contain duplicate items"})}t.items&&e.forEach((o,s)=>k(o,t.items,`${n}[${s}]`,i,r));return}if(t.type==="string"){if(typeof e!="string"){r.push({path:n,message:`must be a string; received ${h(e)}`});return}t.minLength!==void 0&&e.length<t.minLength&&r.push({path:n,message:`must contain at least ${t.minLength} character(s)`});return}if(t.type==="boolean"){typeof e!="boolean"&&r.push({path:n,message:`must be a boolean; received ${h(e)}`});return}if(t.type==="integer"){if(!Number.isInteger(e)){r.push({path:n,message:`must be an integer; received ${h(e)}`});return}t.minimum!==void 0&&e<t.minimum&&r.push({path:n,message:`must be at least ${t.minimum}`})}}function fe(e){return{...e,$schema:e.$schema===void 0?O:e.$schema,schemaVersion:e.schemaVersion===void 0?"1.0":e.schemaVersion,include:e.include===void 0?["src"]:e.include,layers:e.layers===void 0?[]:e.layers,rules:e.rules===void 0?K.map(t=>({...t})):e.rules}}function de(e,t="ark.config.json"){if(!W(e))throw new A(t,[{path:"$",message:`must be an object; received ${h(e)}`}]);let n=e.schemaVersion===void 0?"unversioned":null;if(e.schemaVersion!==void 0&&e.schemaVersion!=="1.0")throw new A(t,[{path:"$.schemaVersion",message:`unsupported version ${JSON.stringify(e.schemaVersion)}; expected 1.0`}]);return{candidate:fe(e),migratedFrom:n}}function ge(e,t="ark.config.json"){let{candidate:n,migratedFrom:i}=de(e,t),r=[];if(k(n,B,"$",B,r),r.length>0)throw new A(t,r);return{config:n,migratedFrom:i}}function q(e,t="ark.config.json"){let n;try{n=JSON.parse(e)}catch(i){throw new A(t,[{path:"$",message:`invalid JSON: ${i instanceof Error?i.message:String(i)}`}])}return ge(n,t)}function m(e){return typeof e=="string"&&e.length>0?e:void 0}function J(e,t){return Number.isInteger(e)&&Number(e)>0?Number(e):t}function pe(e,t,n){return e==="LAYER_IMPORT_VIOLATION"?t.typeOnly||n.targetTypeOnlyExports===!0||n.namedBindingsTypeOnly===!0?"Move the referenced type to a mutually allowed layer, use `import type`, then preflight again.":n.peerIsolation===!0?"Extract the shared dependency to a shared layer, then preflight again.":`Define a port in ${t.fromLayer??"the source layer"}, inject the ${t.toLayer??"outer-layer"} implementation, then preflight again.`:e==="FORBIDDEN_GLOBAL"?`Inject ${t.target??"the capability"} through a port, then preflight again.`:e==="CIRCULAR_DEPENDENCY"?"Extract the shared dependency into a third module, then preflight again.":e==="RAW_EVENT_PUBLISH"?"Publish through a registered intent creator, then run Ark again.":e==="PUBLISH_MISSING_SOURCE"?"Add metadata.source to the publish call, then run Ark again.":`Resolve ${e} without weakening ark.config.json, then run Ark again.`}function Y(e,t="error"){let n=m(e.ruleId)??m(e.code)??"ARK_UNKNOWN",i=e.severity==="warning"?"warning":t,r={...m(e.target)?{target:m(e.target)}:{},...m(e.fromLayer)?{fromLayer:m(e.fromLayer)}:{},...m(e.toLayer)?{toLayer:m(e.toLayer)}:{},...typeof e.typeOnly=="boolean"?{typeOnly:e.typeOnly}:{}};return{ruleId:n,severity:i,message:m(e.message)??n,location:{file:m(e.file)??"<unknown>",line:J(e.line,1),column:J(e.column,1)},evidence:r,nextAction:m(e.nextAction)??pe(n,r,e)}}var z={RAW_EVENT_PUBLISH:"Publish through a registered intent creator; raw event objects or intent strings bypass Ark contracts and tooling.",PUBLISH_MISSING_SOURCE:"Strict Ark publish calls must include metadata.source."};function me(e){return/^(Domain|Application|Adapter|Workflow|Job|Presentation|Reporting|Metadata|Security|Audit|Observability|Kernel)\.[A-Za-z0-9_.]+$/.test(e)}function $(e){if(!e.publishCall)return[];let t=[];return(e.rawIntentName!==void 0&&me(e.rawIntentName)||e.objectHasIntent)&&t.push({ruleId:"RAW_EVENT_PUBLISH",message:z.RAW_EVENT_PUBLISH}),e.arkPublishCandidate&&!e.hasSource&&t.push({ruleId:"PUBLISH_MISSING_SOURCE",message:z.PUBLISH_MISSING_SOURCE}),t}function I(e){if(typeof e.physicalFilename=="string"&&e.physicalFilename.length>0)return e.physicalFilename;if(typeof e.filename=="string"&&e.filename.length>0)return e.filename;if(typeof e.getFilename=="function")try{let t=e.getFilename();if(typeof t=="string"&&t.length>0)return t}catch{}return""}function C(e,t,n,i,r){let o=Y({...i,line:i.line??t.loc?.start?.line,column:i.column??(typeof t.loc?.start?.column=="number"?t.loc.start.column+1:void 0)});return e.report({node:t,messageId:n,...r?{data:r}:{},diagnostic:o}),o}function Q(e){if(!e||e==="<input>"||e.startsWith("stdin"))return null;let t=u.dirname(u.resolve(e));for(;;){let n=u.join(t,"ark.config.json");if(b.existsSync(n))return n;let i=u.dirname(t);if(i===t)return null;t=i}}var P=new Map;function X(e){if(P.has(e))return P.get(e)??null;if(!b.existsSync(e))return null;let t=q(b.readFileSync(e,"utf8"),e).config;return P.set(e,t),t}function ye(e,t){if(!t.startsWith("."))return null;let n=u.resolve(u.dirname(e),t),i=[n,`${n}.ts`,`${n}.tsx`,`${n}.mts`,`${n}.cts`,`${n}.js`,`${n}.jsx`,u.join(n,"index.ts"),u.join(n,"index.tsx"),u.join(n,"index.js")];for(let r of i)try{if(b.existsSync(r)&&b.statSync(r).isFile())return r}catch{}return`${n}.ts`}function E(e){return typeof e?.value=="string"?e.value:void 0}function V(e){return e?.name??E(e)}function F(e){return e.sourceCode??e.getSourceCode?.()}function ee(e,t){let n=F(e)?.getScope?.(t);for(;n;){let i=n.references?.find(r=>r.identifier===t);if(i)return i;n=n.upper??void 0}}function Z(e,t,n){let i=ee(e,t);if(i?.resolved)return(i.resolved.defs?.length??0)>0;let r=F(e)?.getScope?.(t);for(;r;){let o=r.set?.get(n);if(o)return(o.defs?.length??0)>0;r=r.upper??void 0}return!1}function he(e,t){let n=ee(e,t);return n?n.isValueReference!==!1:t.parent?.type==="VariableDeclarator"&&t.parent.init===t}function te(e){if(e?.type==="Identifier"&&e.name)return{root:e,segments:[e.name]};if(!e||!(e.type==="MemberExpression"||!!(e.object&&e.property))||e.computed===!0)return;let n=te(e.object),i=V(e.property);if(!(!n||!i))return{root:n.root,segments:[...n.segments,i]}}function Ae(e){return V(e.callee?.property)}function ne(e,t){return e?.properties?.find(n=>V(n.key)===t)}function R(e,t){return ne(e,t)!==void 0}function be(e){let t=ne(e,"metadata")?.value;return R(t,"source")}function re(e){return Ae(e)==="publish"}var Se={meta:{type:"problem",docs:{description:"Disallow imports that violate ark.config.json layer rules (same contract as arkgate-check)."},messages:{forbiddenImport:"Architecture: {{fromLayer}} must not import {{toLayer}} (ark.config.json). Specifier: {{specifier}}",forbiddenImportHeuristic:"Domain code must not import infrastructure, adapters, repositories, or database modules."},schema:[]},create(e){let t=I(e),n=Q(t),i=n?X(n):null,r=n?u.dirname(n):null,o=s=>{let a=E(s.source);if(a&&i&&r&&t){let f=u.isAbsolute(t)?t:u.resolve(t),g=u.relative(r,f).split(u.sep).join("/"),l=S(g,i.layers);if(!l)return;let c=ye(f,a);if(!c)return;let d=u.relative(r,c).split(u.sep).join("/");if(d.startsWith(".."))return;let p=S(d,i.layers);if(!p)return;U(i.rules,l,p,{fromPath:g,toPath:d,layers:i.layers})&&C(e,s,"forbiddenImport",{ruleId:"LAYER_IMPORT_VIOLATION",file:g,fromLayer:l,toLayer:p,target:d,...s.importKind==="type"?{typeOnly:!0}:{},message:`${l} must not import ${p}.`},{fromLayer:l,toLayer:p,specifier:a});return}};return{ImportDeclaration:o,ExportNamedDeclaration:o,ExportAllDeclaration:o}}},ke={meta:{type:"problem",docs:{description:"Require event bus publish calls to use registered intent creators instead of raw event objects or intent strings."},messages:{rawPublish:"Publish through a registered intent creator; raw event objects or intent strings bypass Ark contracts."},schema:[]},create(e){return{CallExpression(t){let n=t.arguments?.[0],i=E(n),r=$({publishCall:re(t),rawIntentName:i,objectHasIntent:R(n,"intent"),arkPublishCandidate:!1,hasSource:!0});if(r.some(o=>o.ruleId==="RAW_EVENT_PUBLISH")){let o=r.find(s=>s.ruleId==="RAW_EVENT_PUBLISH");C(e,t,"rawPublish",{...o,file:I(e)})}}}}},Re={meta:{type:"problem",docs:{description:"Require event bus publish calls to include source metadata."},messages:{missingSource:"Strict Ark publish calls must include metadata.source."},schema:[]},create(e){return{CallExpression(t){let n=t.arguments?.[0],i=t.arguments?.[2],o=$({publishCall:re(t),rawIntentName:E(n),objectHasIntent:R(n,"intent"),arkPublishCandidate:!0,hasSource:be(n)||R(i,"source")}).find(s=>s.ruleId==="PUBLISH_MISSING_SOURCE");o&&C(e,t,"missingSource",{...o,file:I(e)})}}}},Ie={meta:{type:"problem",docs:{description:"Disallow ambient globals from the layer\u2019s forbiddenGlobals in ark.config.json (same purity surface as ark-check). Option `globals` explicitly overrides."},messages:{forbiddenGlobal:'Ambient global "{{name}}" is forbidden in {{layer}} (ark.config.json); inject the capability through a port instead.',forbiddenGlobalDefault:'Ambient global "{{name}}" is forbidden here; inject the capability through a port instead.'},schema:[{type:"object",properties:{globals:{type:"array",items:{type:"string"}}},additionalProperties:!1}]},create(e){let t=I(e),n=e.options?.[0],i=Q(t),r=i?X(i):null,o=i?u.dirname(i):null,s=null,a="this layer";if(n?.globals)s=new Set(n.globals);else if(r&&o&&t){let l=u.isAbsolute(t)?t:u.resolve(t),c=u.relative(o,l).split(u.sep).join("/"),d=r.layers?.find(p=>p.name===S(c,r.layers));d?.forbiddenGlobals?.length?(s=new Set(d.forbiddenGlobals),a=d.name):s=null}if(!s)return{};let f=typeof F(e)?.getScope=="function",g=(l,c)=>{let d=u.isAbsolute(t)?t:u.resolve(t),p=o?u.relative(o,d).split(u.sep).join("/"):t;C(e,l,r?"forbiddenGlobal":"forbiddenGlobalDefault",{ruleId:"FORBIDDEN_GLOBAL",file:p,fromLayer:a,target:c,message:`${a} must not use the ambient global "${c}".`},{name:c,layer:a})};return{MemberExpression(l){if(l.parent?.type==="MemberExpression"&&l.parent.object===l)return;let c=te(l);if(!c||Z(e,c.root,c.segments[0]))return;let d=c.segments[0]==="globalThis",p=d?c.segments.slice(1):c.segments,N;for(let x=p.length;x>=(d?1:2);x-=1){let M=p.slice(0,x).join(".");if(s.has(M)){N=M;break}}N?g(l,N):!f&&s.has(c.segments[0])&&g(l,c.segments[0])},CallExpression(l){if(f)return;let c=l.callee?.type==="Identifier"?l.callee.name:void 0;c&&s.has(c)&&g(l,c)},NewExpression(l){if(f)return;let c=l.callee?.type==="Identifier"?l.callee.name:void 0;c&&s.has(c)&&g(l,c)},Identifier(l){!f||!l.name||!s.has(l.name)||!he(e,l)||Z(e,l,l.name)||g(l,l.name)}}}},Ce={"no-domain-infra-imports":Se,"no-raw-event-publish":ke,"require-publish-source":Re,"no-forbidden-globals":Ie},j={rules:Ce};j.configs={recommended:{plugins:{ark:j},rules:{"ark/no-domain-infra-imports":"error","ark/no-raw-event-publish":"error","ark/require-publish-source":"error","ark/no-forbidden-globals":"error"}}};var Ve=j;export{Ve as default,Q as findConfigPath,w as globToRegExp,U as isEdgeDenied,S as layerForRelativePath,X as loadArkConfig,Se as noDomainInfraImports,Ie as noForbiddenGlobals,ke as noRawEventPublish,H as patternSpecificity,j as plugin,Re as requirePublishSource,ye as resolveRelativeImport};
3
+ `)}`),this.name="ArkConfigValidationError",this.source=t,this.issues=n}};function Q(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}function O(e,t){return/^[A-Za-z_$][A-Za-z0-9_$]*$/.test(t)?`${e}.${t}`:`${e}[${JSON.stringify(t)}]`}function h(e){return e===null?"null":Array.isArray(e)?"array":typeof e}function me(e,t){let n="#/$defs/";if(e.startsWith(n))return t.$defs[e.slice(n.length)]}function C(e,t,n,i,r){if(t.$ref){let s=me(t.$ref,i);if(!s){r.push({path:n,message:`schema reference ${t.$ref} cannot be resolved`});return}C(e,s,n,i,r);return}if(t.const!==void 0&&!Object.is(e,t.const)){r.push({path:n,message:`must equal ${JSON.stringify(t.const)}`});return}if(t.enum&&!t.enum.some(s=>Object.is(s,e))){r.push({path:n,message:`must be one of ${t.enum.map(String).join(", ")}`});return}if(t.type==="object"){if(!Q(e)){r.push({path:n,message:`must be an object; received ${h(e)}`});return}let s=t.properties??{};for(let l of t.required??[])e[l]===void 0&&r.push({path:O(n,l),message:"is required"});if(t.additionalProperties===!1)for(let l of Object.keys(e))l in s||r.push({path:O(n,l),message:"unknown field"});for(let[l,c]of Object.entries(s))e[l]!==void 0&&C(e[l],c,O(n,l),i,r);return}if(t.type==="array"){if(!Array.isArray(e)){r.push({path:n,message:`must be an array; received ${h(e)}`});return}if(t.minItems!==void 0&&e.length<t.minItems&&r.push({path:n,message:`must contain at least ${t.minItems} item(s)`}),t.uniqueItems){let s=e.map(l=>JSON.stringify(l));new Set(s).size!==s.length&&r.push({path:n,message:"must not contain duplicate items"})}t.items&&e.forEach((s,l)=>C(s,t.items,`${n}[${l}]`,i,r));return}if(t.type==="string"){if(typeof e!="string"){r.push({path:n,message:`must be a string; received ${h(e)}`});return}t.minLength!==void 0&&e.length<t.minLength&&r.push({path:n,message:`must contain at least ${t.minLength} character(s)`});return}if(t.type==="boolean"){typeof e!="boolean"&&r.push({path:n,message:`must be a boolean; received ${h(e)}`});return}if(t.type==="integer"){if(!Number.isInteger(e)){r.push({path:n,message:`must be an integer; received ${h(e)}`});return}t.minimum!==void 0&&e<t.minimum&&r.push({path:n,message:`must be at least ${t.minimum}`})}}function ye(e){return{...e,$schema:e.$schema===void 0?$:e.$schema,schemaVersion:e.schemaVersion===void 0?"1.0":e.schemaVersion,include:e.include===void 0?["src"]:e.include,layers:e.layers===void 0?[]:e.layers,rules:e.rules===void 0?X.map(t=>({...t})):e.rules}}function be(e,t="ark.config.json"){if(!Q(e))throw new A(t,[{path:"$",message:`must be an object; received ${h(e)}`}]);let n=e.schemaVersion===void 0?"unversioned":null;if(e.schemaVersion!==void 0&&e.schemaVersion!=="1.0")throw new A(t,[{path:"$.schemaVersion",message:`unsupported version ${JSON.stringify(e.schemaVersion)}; expected 1.0`}]);return{candidate:ye(e),migratedFrom:n}}function he(e,t="ark.config.json"){let{candidate:n,migratedFrom:i}=be(e,t),r=[];if(C(n,Z,"$",Z,r),r.length>0)throw new A(t,r);return{config:n,migratedFrom:i}}function ee(e,t="ark.config.json"){let n;try{n=JSON.parse(e)}catch(i){throw new A(t,[{path:"$",message:`invalid JSON: ${i instanceof Error?i.message:String(i)}`}])}return he(n,t)}function m(e){return typeof e=="string"&&e.length>0?e:void 0}function te(e,t){return Number.isInteger(e)&&Number(e)>0?Number(e):t}function Ae(e,t,n){return e==="LAYER_IMPORT_VIOLATION"?t.typeOnly||n.targetTypeOnlyExports===!0||n.namedBindingsTypeOnly===!0?"Move the referenced type to a mutually allowed layer, use `import type`, then preflight again.":n.peerIsolation===!0?"Extract the shared dependency to a shared layer, then preflight again.":`Define a port in ${t.fromLayer??"the source layer"}, inject the ${t.toLayer??"outer-layer"} implementation, then preflight again.`:e==="FORBIDDEN_GLOBAL"?`Inject ${t.target??"the capability"} through a port, then preflight again.`:e==="CAPABILITY_VIOLATION"?`Define a ${m(n.capability)??"capability"} port in ${t.fromLayer??"the walled layer"}, bind the implementation outside it, then preflight again.`:e==="CIRCULAR_DEPENDENCY"?"Extract the shared dependency into a third module, then preflight again.":e==="RAW_EVENT_PUBLISH"?"Publish through a registered intent creator, then run Ark again.":e==="PUBLISH_MISSING_SOURCE"?"Add metadata.source to the publish call, then run Ark again.":`Resolve ${e} without weakening ark.config.json, then run Ark again.`}function ne(e,t="error"){let n=m(e.ruleId)??m(e.code)??"ARK_UNKNOWN",i=e.severity==="warning"?"warning":t,r={...m(e.target)?{target:m(e.target)}:{},...m(e.fromLayer)?{fromLayer:m(e.fromLayer)}:{},...m(e.toLayer)?{toLayer:m(e.toLayer)}:{},...typeof e.typeOnly=="boolean"?{typeOnly:e.typeOnly}:{}};return{ruleId:n,severity:i,message:m(e.message)??n,location:{file:m(e.file)??"<unknown>",line:te(e.line,1),column:te(e.column,1)},evidence:r,nextAction:m(e.nextAction)??Ae(n,r,e)}}var re={RAW_EVENT_PUBLISH:"Publish through a registered intent creator; raw event objects or intent strings bypass Ark contracts and tooling.",PUBLISH_MISSING_SOURCE:"Strict Ark publish calls must include metadata.source."};function ke(e){return/^(Domain|Application|Adapter|Workflow|Job|Presentation|Reporting|Metadata|Security|Audit|Observability|Kernel)\.[A-Za-z0-9_.]+$/.test(e)}function P(e){if(!e.publishCall)return[];let t=[];return(e.rawIntentName!==void 0&&ke(e.rawIntentName)||e.objectHasIntent)&&t.push({ruleId:"RAW_EVENT_PUBLISH",message:re.RAW_EVENT_PUBLISH}),e.arkPublishCandidate&&!e.hasSource&&t.push({ruleId:"PUBLISH_MISSING_SOURCE",message:re.PUBLISH_MISSING_SOURCE}),t}function I(e){if(typeof e.physicalFilename=="string"&&e.physicalFilename.length>0)return e.physicalFilename;if(typeof e.filename=="string"&&e.filename.length>0)return e.filename;if(typeof e.getFilename=="function")try{let t=e.getFilename();if(typeof t=="string"&&t.length>0)return t}catch{}return""}function w(e,t,n,i,r){let s=ne({...i,line:i.line??t.loc?.start?.line,column:i.column??(typeof t.loc?.start?.column=="number"?t.loc.start.column+1:void 0)});return e.report({node:t,messageId:n,...r?{data:r}:{},diagnostic:s}),s}function D(e){if(!e||e==="<input>"||e.startsWith("stdin"))return null;let t=u.dirname(u.resolve(e));for(;;){let n=u.join(t,"ark.config.json");if(S.existsSync(n))return n;let i=u.dirname(t);if(i===t)return null;t=i}}var j=new Map;function M(e){if(j.has(e))return j.get(e)??null;if(!S.existsSync(e))return null;let t=ee(S.readFileSync(e,"utf8"),e).config;return j.set(e,t),t}function Se(e,t){if(!t.startsWith("."))return null;let n=u.resolve(u.dirname(e),t),i=[n,`${n}.ts`,`${n}.tsx`,`${n}.mts`,`${n}.cts`,`${n}.js`,`${n}.jsx`,u.join(n,"index.ts"),u.join(n,"index.tsx"),u.join(n,"index.js")];for(let r of i)try{if(S.existsSync(r)&&S.statSync(r).isFile())return r}catch{}return`${n}.ts`}function x(e){return typeof e?.value=="string"?e.value:void 0}function T(e){return e?.name??x(e)}function v(e){return e.sourceCode??e.getSourceCode?.()}function ie(e,t){let n=v(e)?.getScope?.(t);for(;n;){let i=n.references?.find(r=>r.identifier===t);if(i)return i;n=n.upper??void 0}}function F(e,t,n){let i=ie(e,t);if(i?.resolved)return(i.resolved.defs?.length??0)>0;let r=v(e)?.getScope?.(t);for(;r;){let s=r.set?.get(n);if(s)return(s.defs?.length??0)>0;r=r.upper??void 0}return!1}function Ie(e,t){let n=ie(e,t);return n?n.isValueReference!==!1:t.parent?.type==="VariableDeclarator"&&t.parent.init===t}function se(e){if(e?.type==="Identifier"&&e.name)return{root:e,segments:[e.name]};if(!e||!(e.type==="MemberExpression"||!!(e.object&&e.property))||e.computed===!0)return;let n=se(e.object),i=T(e.property);if(!(!n||!i))return{root:n.root,segments:[...n.segments,i]}}function we(e){return T(e.callee?.property)}function oe(e,t){return e?.properties?.find(n=>T(n.key)===t)}function R(e,t){return oe(e,t)!==void 0}function Ce(e){let t=oe(e,"metadata")?.value;return R(t,"source")}function ae(e){return we(e)==="publish"}var Re={meta:{type:"problem",docs:{description:"Disallow imports that violate ark.config.json layer rules (same contract as arkgate-check)."},messages:{forbiddenImport:"Architecture: {{fromLayer}} must not import {{toLayer}} (ark.config.json). Specifier: {{specifier}}",forbiddenImportHeuristic:"Domain code must not import infrastructure, adapters, repositories, or database modules."},schema:[]},create(e){let t=I(e),n=D(t),i=n?M(n):null,r=n?u.dirname(n):null,s=l=>{let c=x(l.source);if(c&&i&&r&&t){let p=u.isAbsolute(t)?t:u.resolve(t),g=u.relative(r,p).split(u.sep).join("/"),o=k(g,i.layers);if(!o)return;let a=Se(p,c);if(!a)return;let d=u.relative(r,a).split(u.sep).join("/");if(d.startsWith(".."))return;let f=k(d,i.layers);if(!f)return;q(i.rules,o,f,{fromPath:g,toPath:d,layers:i.layers})&&w(e,l,"forbiddenImport",{ruleId:"LAYER_IMPORT_VIOLATION",file:g,fromLayer:o,toLayer:f,target:d,...l.importKind==="type"?{typeOnly:!0}:{},message:`${o} must not import ${f}.`},{fromLayer:o,toLayer:f,specifier:c});return}};return{ImportDeclaration:s,ExportNamedDeclaration:s,ExportAllDeclaration:s}}},xe={meta:{type:"problem",docs:{description:"Require event bus publish calls to use registered intent creators instead of raw event objects or intent strings."},messages:{rawPublish:"Publish through a registered intent creator; raw event objects or intent strings bypass Ark contracts."},schema:[]},create(e){return{CallExpression(t){let n=t.arguments?.[0],i=x(n),r=P({publishCall:ae(t),rawIntentName:i,objectHasIntent:R(n,"intent"),arkPublishCandidate:!1,hasSource:!0});if(r.some(s=>s.ruleId==="RAW_EVENT_PUBLISH")){let s=r.find(l=>l.ruleId==="RAW_EVENT_PUBLISH");w(e,t,"rawPublish",{...s,file:I(e)})}}}}},Ee={meta:{type:"problem",docs:{description:"Require event bus publish calls to include source metadata."},messages:{missingSource:"Strict Ark publish calls must include metadata.source."},schema:[]},create(e){return{CallExpression(t){let n=t.arguments?.[0],i=t.arguments?.[2],s=P({publishCall:ae(t),rawIntentName:x(n),objectHasIntent:R(n,"intent"),arkPublishCandidate:!0,hasSource:Ce(n)||R(i,"source")}).find(l=>l.ruleId==="PUBLISH_MISSING_SOURCE");s&&w(e,t,"missingSource",{...s,file:I(e)})}}}},Ne={meta:{type:"problem",docs:{description:"Disallow ambient globals from the layer\u2019s forbiddenGlobals in ark.config.json (same purity surface as ark-check). Option `globals` explicitly overrides."},messages:{forbiddenGlobal:'Ambient global "{{name}}" is forbidden in {{layer}} (ark.config.json); inject the capability through a port instead.',forbiddenGlobalDefault:'Ambient global "{{name}}" is forbidden here; inject the capability through a port instead.'},schema:[{type:"object",properties:{globals:{type:"array",items:{type:"string"}}},additionalProperties:!1}]},create(e){let t=I(e),n=e.options?.[0],i=D(t),r=i?M(i):null,s=i?u.dirname(i):null,l=null,c="this layer";if(n?.globals)l=new Set(n.globals);else if(r&&s&&t){let o=u.isAbsolute(t)?t:u.resolve(t),a=u.relative(s,o).split(u.sep).join("/"),d=r.layers?.find(f=>f.name===k(a,r.layers));d?.forbiddenGlobals?.length?(l=new Set(d.forbiddenGlobals),c=d.name):l=null}if(!l)return{};let p=typeof v(e)?.getScope=="function",g=(o,a)=>{let d=u.isAbsolute(t)?t:u.resolve(t),f=s?u.relative(s,d).split(u.sep).join("/"):t;w(e,o,r?"forbiddenGlobal":"forbiddenGlobalDefault",{ruleId:"FORBIDDEN_GLOBAL",file:f,fromLayer:c,target:a,message:`${c} must not use the ambient global "${a}".`},{name:a,layer:c})};return{MemberExpression(o){if(o.parent?.type==="MemberExpression"&&o.parent.object===o)return;let a=se(o);if(!a||F(e,a.root,a.segments[0]))return;let d=a.segments[0]==="globalThis",f=d?a.segments.slice(1):a.segments,y;for(let E=f.length;E>=(d?1:2);E-=1){let G=f.slice(0,E).join(".");if(l.has(G)){y=G;break}}y?g(o,y):!p&&l.has(a.segments[0])&&g(o,a.segments[0])},CallExpression(o){if(p)return;let a=o.callee?.type==="Identifier"?o.callee.name:void 0;a&&l.has(a)&&g(o,a)},NewExpression(o){if(p)return;let a=o.callee?.type==="Identifier"?o.callee.name:void 0;a&&l.has(a)&&g(o,a)},Identifier(o){!p||!o.name||!l.has(o.name)||!Ie(e,o)||F(e,o,o.name)||g(o,o.name)}}}},Le={meta:{type:"problem",docs:{description:"Disallow importing modules whose effect capability the layer denies (ark.config.json capabilities.deny / pure \u2014 same wall surface as ark-check). Import dimension only: ambient globals stay with no-forbidden-globals and the CLI/hook symbol path."},messages:{deniedCapability:'{{layer}} denies the {{capability}} capability (ark.config.json); "{{specifier}}" imports it. Define a port and bind the implementation in an adapter layer.'},schema:[]},create(e){let t=I(e),n=D(t),i=n?M(n):null,r=n?u.dirname(n):null;if(!i||!r||!t)return{};let s=u.isAbsolute(t)?t:u.resolve(t),l=u.relative(r,s).split(u.sep).join("/"),c=i.layers?.find(o=>o.name===k(l,i.layers));if(!c)return{};let p=new Set(z(c));if(p.size===0)return{};let g=(o,a,d)=>{if(d||typeof a!="string")return;let f=Y(a);!f||!p.has(f)||w(e,o,"deniedCapability",{ruleId:"CAPABILITY_VIOLATION",file:l,fromLayer:c.name,target:a,capability:f,message:`${c.name} denies the ${f} capability; found import of "${a}".`},{layer:c.name,capability:f,specifier:a})};return{ImportDeclaration(o){let a=o,d=(a.specifiers??[]).filter(y=>y.type==="ImportSpecifier"),f=d.length>0&&d.length===(a.specifiers??[]).length&&d.every(y=>y.importKind==="type");g(o,a.source?.value,a.importKind==="type"||f)},ImportExpression(o){let a=o;a.source?.type==="Literal"&&g(o,a.source.value,!1)},ExportNamedDeclaration(o){let a=o;if(!a.source)return;let d=a.specifiers??[],f=d.length>0&&d.every(y=>y.exportKind==="type");g(o,a.source.value,a.exportKind==="type"||f)},ExportAllDeclaration(o){let a=o;g(o,a.source?.value,a.exportKind==="type")},CallExpression(o){let a=o;a.callee?.type==="Identifier"&&a.callee.name==="require"&&a.arguments?.[0]?.type==="Literal"&&!F(e,o,"require")&&g(o,a.arguments[0].value,!1)}}}},_e={"no-domain-infra-imports":Re,"no-raw-event-publish":xe,"require-publish-source":Ee,"no-forbidden-globals":Ne,"no-denied-capabilities":Le},V={rules:_e};V.configs={recommended:{plugins:{ark:V},rules:{"ark/no-domain-infra-imports":"error","ark/no-raw-event-publish":"error","ark/require-publish-source":"error","ark/no-forbidden-globals":"error","ark/no-denied-capabilities":"error"}}};var Ke=V;export{Ke as default,D as findConfigPath,N as globToRegExp,q as isEdgeDenied,k as layerForRelativePath,M as loadArkConfig,Le as noDeniedCapabilities,Re as noDomainInfraImports,Ne as noForbiddenGlobals,xe as noRawEventPublish,U as patternSpecificity,V as plugin,Ee as requirePublishSource,Se as resolveRelativeImport};