arkgate 3.6.0 → 3.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/CHANGELOG.md +69 -0
  2. package/README.md +4 -5
  3. package/bin/ark-check.mjs +3 -3
  4. package/bin/ark-layer-match.mjs +2 -1
  5. package/bin/ark.mjs +2 -2
  6. package/bin/lib/agent-gates.mjs +2 -0
  7. package/bin/lib/analysis-engine.mjs +6 -6
  8. package/bin/lib/architecture-scan.mjs +66 -13
  9. package/bin/lib/ci-and-commands.mjs +5 -8
  10. package/bin/lib/codex-home.mjs +21 -6
  11. package/bin/lib/design-smells.mjs +67 -14
  12. package/bin/lib/doctor-advisories.mjs +20 -5
  13. package/bin/lib/doctor-plan.mjs +5 -7
  14. package/bin/lib/gate-files.mjs +1 -1
  15. package/bin/lib/hook-templates.mjs +21 -1
  16. package/bin/lib/html-report-advisories.mjs +59 -0
  17. package/bin/lib/install-migrate.mjs +26 -11
  18. package/bin/lib/mcp-adoption.mjs +21 -4
  19. package/bin/lib/parse-health.mjs +74 -0
  20. package/bin/lib/reshape-decisions.mjs +284 -0
  21. package/bin/lib/ts-resolve.mjs +3 -2
  22. package/bin/lib/write-path-capabilities.mjs +6 -0
  23. package/dist/eslint/index.cjs +2 -2
  24. package/dist/eslint/index.js +2 -2
  25. package/dist/index.cjs +7 -7
  26. package/dist/index.d.cts +1 -1
  27. package/dist/index.d.ts +1 -1
  28. package/dist/index.js +6 -6
  29. package/docs/agent-guide.md +34 -3
  30. package/docs/ai-gates.md +21 -18
  31. package/docs/configuration.md +6 -0
  32. package/docs/enthusiast/how-to-agent-gates.md +1 -1
  33. package/docs/package-surface.md +6 -5
  34. package/docs/typescript-support.md +9 -0
  35. package/package.json +2 -1
  36. package/server.json +2 -2
  37. package/templates/skills/ark-autopilot.md +12 -0
  38. package/templates/skills/ark-explore.md +8 -1
  39. package/templates/skills/ark-fix.md +11 -1
  40. package/templates/skills/ark-loop.md +14 -1
@@ -0,0 +1,284 @@
1
+ /**
2
+ * Y01 — explicit verdict memory for X04 reshape pilots.
3
+ *
4
+ * Decisions bind to a concept plus its complete, sorted anchor set. Counts,
5
+ * move samples, and change-map hashes are deliberately excluded: evidence may
6
+ * drift without overturning an adopter's verdict, while a changed physical
7
+ * layout makes the old record stale. Advisory only; mirror facts stay intact.
8
+ */
9
+ import fs from 'node:fs';
10
+ import path from 'node:path';
11
+ import { classifyPhysical, computeReshapePilot } from './physical-cohesion.mjs';
12
+
13
+ export const RESHAPE_DECISIONS_PATH = '.ark/reshape-decisions.json';
14
+
15
+ const MAX_DECISION_BYTES = 64 * 1024;
16
+ const MAX_DECISIONS = 200;
17
+ const MAX_LIFECYCLE_ITEMS = 12;
18
+ const MAX_ANCHOR_EVIDENCE = 20;
19
+ const VERDICTS = new Set(['accepted', 'deferred', 'rejected']);
20
+
21
+ function normalizeAnchor(raw) {
22
+ const portable = String(raw).trim().replace(/\\/g, '/');
23
+ if (portable === '.') return '.';
24
+ if (!portable || portable.startsWith('/') || /^[A-Za-z]:\//.test(portable) || portable.includes('\0')) {
25
+ return null;
26
+ }
27
+ const segments = portable.split('/');
28
+ if (segments.some((segment) => !segment || segment === '.' || segment === '..')) return null;
29
+ return segments.join('/');
30
+ }
31
+
32
+ function targetKey(concept, anchors) {
33
+ return JSON.stringify([concept, anchors]);
34
+ }
35
+
36
+ function compareText(left, right) {
37
+ return left < right ? -1 : left > right ? 1 : 0;
38
+ }
39
+
40
+ function sameStrings(left, right) {
41
+ return left.length === right.length && left.every((value, index) => value === right[index]);
42
+ }
43
+
44
+ function lifecycleStatus(decision, today) {
45
+ const reviewBy = decision.reviewBy;
46
+ if (reviewBy === undefined) return 'undated';
47
+ if (!/^\d{4}-\d{2}-\d{2}$/.test(reviewBy)) return 'malformed';
48
+ const date = new Date(`${reviewBy}T00:00:00.000Z`);
49
+ if (Number.isNaN(date.getTime()) || date.toISOString().slice(0, 10) !== reviewBy) {
50
+ return 'malformed';
51
+ }
52
+ return typeof today === 'string' && reviewBy < today ? 'expired' : 'current';
53
+ }
54
+
55
+ /** Bounded, fail-loud loader. A broken file never suppresses a pilot. */
56
+ export function loadReshapeDecisions(root) {
57
+ const relPath = RESHAPE_DECISIONS_PATH;
58
+ const abs = path.join(root, relPath);
59
+ let stats;
60
+ try {
61
+ stats = fs.statSync(abs);
62
+ } catch {
63
+ return { path: relPath, exists: false, decisions: [] };
64
+ }
65
+ const invalid = (error) => ({ path: relPath, exists: true, invalid: true, error, decisions: [] });
66
+ if (!stats.isFile()) return invalid('not a regular file');
67
+ if (stats.size > MAX_DECISION_BYTES) {
68
+ return invalid(`larger than ${MAX_DECISION_BYTES} bytes`);
69
+ }
70
+ let parsed;
71
+ try {
72
+ parsed = JSON.parse(fs.readFileSync(abs, 'utf8'));
73
+ } catch (error) {
74
+ return invalid(error instanceof Error ? error.message : 'unreadable JSON');
75
+ }
76
+ if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
77
+ return invalid('expected an object with decisions[]');
78
+ }
79
+ const unknownTop = Object.keys(parsed).filter((key) => !['schemaVersion', 'decisions'].includes(key));
80
+ if (unknownTop.length > 0) return invalid(`unknown field: ${unknownTop[0]}`);
81
+ if (parsed.schemaVersion !== undefined && parsed.schemaVersion !== '1') {
82
+ return invalid('schemaVersion must be "1" when present');
83
+ }
84
+ if (!Array.isArray(parsed.decisions)) return invalid('expected { decisions: [...] }');
85
+ if (parsed.decisions.length > MAX_DECISIONS) {
86
+ return invalid(`more than ${MAX_DECISIONS} entries`);
87
+ }
88
+
89
+ const decisions = [];
90
+ const seen = new Set();
91
+ for (const entry of parsed.decisions) {
92
+ if (!entry || typeof entry !== 'object' || Array.isArray(entry)) {
93
+ return invalid('every decision must be an object');
94
+ }
95
+ const unknown = Object.keys(entry).filter((key) =>
96
+ !['concept', 'anchors', 'verdict', 'reason', 'reviewBy'].includes(key)
97
+ );
98
+ if (unknown.length > 0) return invalid(`decision has unknown field: ${unknown[0]}`);
99
+ const concept = typeof entry.concept === 'string' ? entry.concept.trim() : '';
100
+ const reason = typeof entry.reason === 'string' ? entry.reason.trim() : '';
101
+ if (!concept || !reason || !VERDICTS.has(entry.verdict)) {
102
+ return invalid('every decision needs concept, verdict (accepted/deferred/rejected), and reason');
103
+ }
104
+ if (entry.reviewBy !== undefined && typeof entry.reviewBy !== 'string') {
105
+ return invalid('reviewBy must be a string when present');
106
+ }
107
+ if (!Array.isArray(entry.anchors) || entry.anchors.length === 0) {
108
+ return invalid('every decision needs a non-empty anchors array');
109
+ }
110
+ if (entry.anchors.some((anchor) => typeof anchor !== 'string')) {
111
+ return invalid('every decision anchor must be a string');
112
+ }
113
+ const anchors = entry.anchors.map(normalizeAnchor);
114
+ if (anchors.some((anchor) => anchor === null)) {
115
+ return invalid('anchors must be canonical project-relative paths');
116
+ }
117
+ anchors.sort();
118
+ if (new Set(anchors).size !== anchors.length) return invalid('decision anchors must be unique');
119
+ const key = targetKey(concept, anchors);
120
+ if (seen.has(key)) return invalid('duplicate decision target');
121
+ seen.add(key);
122
+ decisions.push({
123
+ concept,
124
+ anchors,
125
+ verdict: entry.verdict,
126
+ reason,
127
+ ...(entry.reviewBy !== undefined ? { reviewBy: entry.reviewBy } : {}),
128
+ });
129
+ }
130
+ decisions.sort(
131
+ (left, right) =>
132
+ compareText(left.concept, right.concept) ||
133
+ compareText(targetKey(left.concept, left.anchors), targetKey(right.concept, right.anchors))
134
+ );
135
+ return { path: relPath, exists: true, decisions };
136
+ }
137
+
138
+ function anchorsByConcept(root, files) {
139
+ const result = new Map();
140
+ const resolvedRoot = path.resolve(root);
141
+ for (const file of Array.isArray(files) ? files : []) {
142
+ const abs = path.isAbsolute(file) ? path.resolve(file) : path.resolve(root, file);
143
+ const rel = path.relative(resolvedRoot, abs);
144
+ if (rel.startsWith('..') || path.isAbsolute(rel)) continue;
145
+ const classified = classifyPhysical(rel);
146
+ if (!classified) continue;
147
+ if (!result.has(classified.concept)) result.set(classified.concept, new Set());
148
+ result.get(classified.concept).add(classified.anchor);
149
+ }
150
+ return new Map([...result].map(([concept, anchors]) => [concept, [...anchors].sort()]));
151
+ }
152
+
153
+ /** Pure lifecycle/staleness resolution; callers inject `today` in tests. */
154
+ export function analyzeReshapeDecisions(
155
+ root,
156
+ files,
157
+ state = { path: RESHAPE_DECISIONS_PATH, exists: false, decisions: [] },
158
+ today = null
159
+ ) {
160
+ const anchorSets = anchorsByConcept(root, files);
161
+ const current = [];
162
+ const expired = [];
163
+ const malformed = [];
164
+ const stale = [];
165
+ for (const decision of state.invalid ? [] : state.decisions ?? []) {
166
+ const currentAnchors = anchorSets.get(decision.concept) ?? [];
167
+ if (!sameStrings(decision.anchors, currentAnchors)) {
168
+ stale.push({
169
+ ...decision,
170
+ currentAnchorCount: currentAnchors.length,
171
+ currentAnchors: currentAnchors.slice(0, MAX_ANCHOR_EVIDENCE),
172
+ });
173
+ continue;
174
+ }
175
+ const status = lifecycleStatus(decision, today);
176
+ if (status === 'expired') expired.push(decision);
177
+ else if (status === 'malformed') malformed.push(decision);
178
+ else {
179
+ current.push({
180
+ ...decision,
181
+ lifecycle: status,
182
+ suppressesPilot: decision.verdict === 'deferred' || decision.verdict === 'rejected',
183
+ });
184
+ }
185
+ }
186
+ const summary = {
187
+ advisory: true,
188
+ explicitOnly: true,
189
+ neverChangesFacts: true,
190
+ decisionFile: {
191
+ path: state.path ?? RESHAPE_DECISIONS_PATH,
192
+ present: state.exists === true,
193
+ invalid: state.invalid === true,
194
+ ...(state.invalid ? { error: state.error ?? 'invalid' } : {}),
195
+ },
196
+ currentCount: current.length,
197
+ current: current.slice(0, MAX_LIFECYCLE_ITEMS),
198
+ lifecycle: {
199
+ undated: current.filter((decision) => decision.lifecycle === 'undated').length,
200
+ malformedCount: malformed.length,
201
+ malformed: malformed.slice(0, MAX_LIFECYCLE_ITEMS),
202
+ expiredCount: expired.length,
203
+ expired: expired.slice(0, MAX_LIFECYCLE_ITEMS),
204
+ staleCount: stale.length,
205
+ stale: stale.slice(0, MAX_LIFECYCLE_ITEMS),
206
+ },
207
+ };
208
+ return { summary, current, anchorSets };
209
+ }
210
+
211
+ /** Filesystem/clock wrapper for doctor and report callers. */
212
+ export function computeReshapeDecisionMemory(root, files, today = new Date().toISOString().slice(0, 10)) {
213
+ return analyzeReshapeDecisions(root, files, loadReshapeDecisions(root), today);
214
+ }
215
+
216
+ /** Select one actionable finding while respecting explicit current verdicts. */
217
+ export function computeDecisionAwareReshapePilot(cohesion, files, root, analysis) {
218
+ const findings = Array.isArray(cohesion?.findings) ? cohesion.findings : [];
219
+ if (findings.length === 0) return null;
220
+ const currentByTarget = new Map(
221
+ analysis.current.map((decision) => [targetKey(decision.concept, decision.anchors), decision])
222
+ );
223
+ for (const finding of findings) {
224
+ const anchors = analysis.anchorSets.get(finding.concept) ?? [];
225
+ const decision = currentByTarget.get(targetKey(finding.concept, anchors));
226
+ if (decision?.suppressesPilot) continue;
227
+ const pilot = computeReshapePilot({ ...cohesion, findings: [finding] }, files, root);
228
+ if (!pilot?.nextPilot) return pilot;
229
+ return {
230
+ ...pilot,
231
+ ...(decision ? { decision } : {}),
232
+ nextPilot: {
233
+ ...pilot.nextPilot,
234
+ decisionTarget: { concept: finding.concept, anchors },
235
+ decisionFile: RESHAPE_DECISIONS_PATH,
236
+ },
237
+ };
238
+ }
239
+ return {
240
+ proposed: false,
241
+ applied: false,
242
+ neverMechanicalSafe: true,
243
+ nextPilot: null,
244
+ suppressedByDecision: true,
245
+ note: 'Every displayed reshape target has an explicit current rejected/deferred decision; mirror facts remain visible.',
246
+ };
247
+ }
248
+
249
+ /** Human doctor section; lifecycle stays visible even after the sensor quiets. */
250
+ export function printReshapeDecisionsSection(memory, io) {
251
+ const lifecycle = memory?.lifecycle;
252
+ const hasContent =
253
+ memory?.decisionFile?.invalid ||
254
+ memory?.currentCount > 0 ||
255
+ lifecycle?.expiredCount > 0 ||
256
+ lifecycle?.malformedCount > 0 ||
257
+ lifecycle?.staleCount > 0;
258
+ if (!hasContent) return;
259
+ console.log('');
260
+ console.log(io.color.bold('Reshape decisions (advisory)'));
261
+ if (memory.decisionFile.invalid) {
262
+ io.line(io.warn, `${memory.decisionFile.path} is present but invalid — decisions are ignored.`);
263
+ }
264
+ for (const decision of memory.current.slice(0, 5)) {
265
+ const review = decision.reviewBy ? ` · review-by ${decision.reviewBy}` : '';
266
+ io.line(' ', `[${decision.concept}] ${decision.verdict}${review} — ${decision.reason}`);
267
+ }
268
+ if (memory.currentCount > memory.current.slice(0, 5).length) {
269
+ io.line(' ', io.color.dim(`…(+${memory.currentCount - 5} more current decision(s))`));
270
+ }
271
+ if (lifecycle.expiredCount > 0) {
272
+ io.line(io.warn, `${lifecycle.expiredCount} reshape decision(s) expired — pilot pressure is active again.`);
273
+ }
274
+ if (lifecycle.malformedCount > 0) {
275
+ io.line(io.warn, `${lifecycle.malformedCount} reshape decision(s) have malformed review-by dates — ignored.`);
276
+ }
277
+ if (lifecycle.staleCount > 0) {
278
+ io.line(io.warn, `${lifecycle.staleCount} reshape decision(s) have a changed anchor set — stale; update or delete them.`);
279
+ }
280
+ if (lifecycle.undated > 0) {
281
+ io.line(' ', io.color.dim(`${lifecycle.undated} current decision(s) have no review-by date.`));
282
+ }
283
+ io.line(' ', io.color.dim('explicit verdicts affect pilot pressure only; physical facts and the gate verdict are unchanged'));
284
+ }
@@ -110,7 +110,7 @@ export function scanCachePath(root) {
110
110
  return path.join(root, 'node_modules', '.cache', 'ark-check.json');
111
111
  }
112
112
 
113
- export function scanCacheKey(root, args) {
113
+ export function scanCacheKey(root, args, parserIdentity = '') {
114
114
  const read = (p) => {
115
115
  try {
116
116
  return fs.readFileSync(p, 'utf8');
@@ -130,9 +130,10 @@ export function scanCacheKey(root, args) {
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
132
  // v8: opted-in capability walls (U04) — stale caches must not miss wall verdicts.
133
+ // v9: per-file parseDiagnosticCount + parser identity (Y03); no raw diagnostics.
133
134
  return crypto
134
135
  .createHash('sha1')
135
- .update(`ark-check-cache-v8\0${read(configPath)}\0${manifestPath ? read(manifestPath) : ''}`)
136
+ .update(`ark-check-cache-v9\0${String(parserIdentity)}\0${read(configPath)}\0${manifestPath ? read(manifestPath) : ''}`)
136
137
  .digest('hex');
137
138
  }
138
139
 
@@ -8,6 +8,7 @@
8
8
  import fs from 'node:fs';
9
9
  import path from 'node:path';
10
10
  import {
11
+ codexProjectMcpIsValid,
11
12
  codexConfigPath,
12
13
  listCodexArkServerTables,
13
14
  } from './codex-home.mjs';
@@ -154,6 +155,11 @@ function mcpEvidence(root, relativePath) {
154
155
  }
155
156
 
156
157
  function codexMcpEvidence(root) {
158
+ const projectFile = path.join(root, '.codex', 'config.toml');
159
+ const projectText = readText(projectFile);
160
+ const projectRegistered = codexProjectMcpIsValid(projectText, root);
161
+ if (projectRegistered) return ['.codex/config.toml'];
162
+
157
163
  const file = codexConfigPath();
158
164
  const text = readText(file);
159
165
  const resolvedRoot = path.resolve(root);
@@ -1,3 +1,3 @@
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}):
1
+ "use strict";var Ae=Object.create;var N=Object.defineProperty;var ke=Object.getOwnPropertyDescriptor;var Se=Object.getOwnPropertyNames;var Ie=Object.getPrototypeOf,we=Object.prototype.hasOwnProperty;var Re=(e,t)=>{for(var n in t)N(e,n,{get:t[n],enumerable:!0})},W=(e,t,n,i)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of Se(t))!we.call(e,r)&&r!==n&&N(e,r,{get:()=>t[r],enumerable:!(i=ke(t,r))||i.enumerable});return e};var z=(e,t,n)=>(n=e!=null?Ae(Ie(e)):{},W(t||!e||!e.__esModule?N(n,"default",{value:e,enumerable:!0}):n,e)),Ce=e=>W(N({},"__esModule",{value:!0}),e);var Ue={};Re(Ue,{default:()=>He,findConfigPath:()=>P,globToRegExp:()=>E,isEdgeDenied:()=>M,layerForRelativePath:()=>A,loadArkConfig:()=>j,noDeniedCapabilities:()=>he,noDomainInfraImports:()=>ge,noForbiddenGlobals:()=>be,noRawEventPublish:()=>me,patternSpecificity:()=>D,plugin:()=>$,requirePublishSource:()=>ye,resolveRelativeImport:()=>ce});module.exports=Ce(Ue);var I=z(require("fs"),1),p=z(require("path"),1);var Y=new Map;function J(e){return/[.*+?^${}()|[\]\\]/.test(e)?`\\${e}`:e}function F(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 xe(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 E(e){let t=Y.get(e);if(t)return t;let n=F(e),i=xe(n),r="",a=0;for(let c=0;c<n.length;c+=1){let f=n[c];f==="\\"&&c+1<n.length?(r+=J(n[c+1]),c+=1):f==="*"?n[c+1]==="*"?n[c+2]==="/"?(r+="(?:.*/)?",c+=2):(r+=".*",c+=1):r+="[^/]*":f==="?"?r+="[^/]":f==="{"&&i?(r+="(?:",a+=1):f==="}"&&i&&a>0?(r+=")",a-=1):f===","&&i&&a>0?r+="|":r+=J(f)}let l=new RegExp(`^${r}$`);return Y.set(e,l),l}function D(e){let t=F(String(e)),i=t.split("*")[0].split("/").filter(Boolean).length,r=t.replace(/\*/g,"").length;return i*1e4+r}function A(e,t){let n=String(e).split(/[/\\]/).join("/"),i,r=-1;for(let a of t??[])if(!(a.exclude??[]).some(l=>E(l).test(n))){for(let l of a.patterns??[])if(E(l).test(n)){let c=D(l);c>r&&(r=c,i=a.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].toLowerCase()}/${n[r+1].toLowerCase()}`}function Ne(e){let t=new Set;for(let n of e??[]){let r=F(String(n)).split("/").filter(Boolean);for(let a=0;a<r.length;a+=1){let l=r[a];if((l==="**"||l==="*")&&a>0){let c=r[a-1];c&&!c.includes("*")&&!c.includes("{")&&!c.includes("}")&&t.add(c)}}}return[...t]}function Ee(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 Ne(i?.patterns)}function Le(e,t,n,i){for(let r of e??[])if(!(r.from!==t||r.to!==n)&&r.allowed===!1){if(r.peerIsolation){let a=i?.fromPath,l=i?.toPath;if(!a||!l)continue;let c=Ee(r,t,i?.layers);if(c.length===0)continue;let f=Z(a,c),g=Z(l,c);if(!f||!g)continue;if(f!==g)return r;continue}if(t!==n)return r}}function M(e,t,n,i){return Le(e,t,n,i)!==void 0}var X=Object.freeze(["network","filesystem","clock","randomness","environment","process","persistence"]),Oe=Object.freeze({fetch:"network",XMLHttpRequest:"network",Date:"clock","Date.now":"clock","Math.random":"randomness","process.env":"environment",process:"process"}),ze=Object.freeze(Object.keys(Oe).sort()),T=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"}),_e=Object.freeze({process:Object.freeze(["process","node:process"])});function Q(e){if(!e||e.startsWith(".")||e.startsWith("/"))return null;let t=T[e];if(t)return t;let n=e.indexOf("/");if(n<0)return null;let i=e.slice(0,n),r=T[i];if(r)return r;let a=e.indexOf("/",n+1);return a<0?null:T[e.slice(0,a)]??null}function V(e,t){for(let n of t)if(_e[n]?.includes(e))return n;return null}function ee(e){if(e?.pure===!0)return[...X].sort();let n=(e?.capabilities?.deny??[]).filter(i=>X.includes(i));return[...new Set(n)].sort()}var K="https://unpkg.com/arkgate@2/schemas/ark.config.schema.json",te=["DomainModel","ApplicationOrchestration","PersistenceAdapters","IntegrationAdapters","WorkflowSagaEngine","BackgroundJobsScheduling","PresentationAdapters","ReportingReadModels","ExtensibilityMetadata","SecurityAuditObservability","Kernel"],$e=new Set(["PresentationAdapters->ApplicationOrchestration","ApplicationOrchestration->DomainModel","WorkflowSagaEngine->ApplicationOrchestration","WorkflowSagaEngine->DomainModel","BackgroundJobsScheduling->ApplicationOrchestration"]);function Pe(){let e=[];for(let t of te)for(let n of te)t===n||$e.has(`${t}->${n}`)||e.push({from:t,to:n,allowed:!1});return e}var re=Pe();var h={type:"array",items:{type:"string",minLength:1},uniqueItems:!0},ne={$schema:"https://json-schema.org/draft/2020-12/schema",$id:K,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:K,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:{...h,minItems:1,default:["src"]},exclude:{...h,default:[]},excludeGenerated:{type:"boolean",default:!0},frameworkOverlay:{type:"string",minLength:1},layers:{type:"array",default:[],items:{$ref:"#/$defs/layer"}},rules:{type:"array",default:re,items:{$ref:"#/$defs/rule"}},cyclePolicy:{type:"string",enum:["strict","soft","framework-soft","off"],default:"strict"},dynamicImportAllowlist:{...h,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:{...h,minItems:1},exclude:h,intentPrefixes:h,description:{type:"string",minLength:1},forbiddenGlobals:h,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:{...h,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}}}}},S=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 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});
3
+ `)}`),this.name="ArkConfigValidationError",this.source=t,this.issues=n}};function ie(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}function G(e,t){return/^[A-Za-z_$][A-Za-z0-9_$]*$/.test(t)?`${e}.${t}`:`${e}[${JSON.stringify(t)}]`}function k(e){return e===null?"null":Array.isArray(e)?"array":typeof e}function je(e,t){let n="#/$defs/";if(e.startsWith(n))return t.$defs[e.slice(n.length)]}function L(e,t,n,i,r){if(t.$ref){let a=je(t.$ref,i);if(!a){r.push({path:n,message:`schema reference ${t.$ref} cannot be resolved`});return}L(e,a,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(a=>Object.is(a,e))){r.push({path:n,message:`must be one of ${t.enum.map(String).join(", ")}`});return}if(t.type==="object"){if(!ie(e)){r.push({path:n,message:`must be an object; received ${k(e)}`});return}let a=t.properties??{};for(let l of t.required??[])e[l]===void 0&&r.push({path:G(n,l),message:"is required"});if(t.additionalProperties===!1)for(let l of Object.keys(e))l in a||r.push({path:G(n,l),message:"unknown field"});for(let[l,c]of Object.entries(a))e[l]!==void 0&&L(e[l],c,G(n,l),i,r);return}if(t.type==="array"){if(!Array.isArray(e)){r.push({path:n,message:`must be an array; received ${k(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 a=e.map(l=>JSON.stringify(l));new Set(a).size!==a.length&&r.push({path:n,message:"must not contain duplicate items"})}t.items&&e.forEach((a,l)=>L(a,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 ${k(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 ${k(e)}`});return}if(t.type==="integer"){if(!Number.isInteger(e)){r.push({path:n,message:`must be an integer; received ${k(e)}`});return}t.minimum!==void 0&&e<t.minimum&&r.push({path:n,message:`must be at least ${t.minimum}`})}}function ve(e){return{...e,$schema:e.$schema===void 0?K: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?re.map(t=>({...t})):e.rules}}function Fe(e,t="ark.config.json"){if(!ie(e))throw new S(t,[{path:"$",message:`must be an object; received ${k(e)}`}]);let n=e.schemaVersion===void 0?"unversioned":null;if(e.schemaVersion!==void 0&&e.schemaVersion!=="1.0")throw new S(t,[{path:"$.schemaVersion",message:`unsupported version ${JSON.stringify(e.schemaVersion)}; expected 1.0`}]);return{candidate:ve(e),migratedFrom:n}}function De(e,t="ark.config.json"){let{candidate:n,migratedFrom:i}=Fe(e,t),r=[];if(L(n,ne,"$",ne,r),r.length>0)throw new S(t,r);return{config:n,migratedFrom:i}}function oe(e,t="ark.config.json"){let n;try{n=JSON.parse(e)}catch(i){throw new S(t,[{path:"$",message:`invalid JSON: ${i instanceof Error?i.message:String(i)}`}])}return De(n,t)}function b(e){return typeof e=="string"&&e.length>0?e:void 0}function se(e,t){return Number.isInteger(e)&&Number(e)>0?Number(e):t}function Me(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 ${b(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 ae(e,t="error"){let n=b(e.ruleId)??b(e.code)??"ARK_UNKNOWN",i=e.severity==="warning"?"warning":t,r={...b(e.target)?{target:b(e.target)}:{},...b(e.fromLayer)?{fromLayer:b(e.fromLayer)}:{},...b(e.toLayer)?{toLayer:b(e.toLayer)}:{},...typeof e.typeOnly=="boolean"?{typeOnly:e.typeOnly}:{}};return{ruleId:n,severity:i,message:b(e.message)??n,location:{file:b(e.file)??"<unknown>",line:se(e.line,1),column:se(e.column,1)},evidence:r,nextAction:b(e.nextAction)??Me(n,r,e)}}var le={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 Te(e){return/^(Domain|Application|Adapter|Workflow|Job|Presentation|Reporting|Metadata|Security|Audit|Observability|Kernel)\.[A-Za-z0-9_.]+$/.test(e)}function B(e){if(!e.publishCall)return[];let t=[];return(e.rawIntentName!==void 0&&Te(e.rawIntentName)||e.objectHasIntent)&&t.push({ruleId:"RAW_EVENT_PUBLISH",message:le.RAW_EVENT_PUBLISH}),e.arkPublishCandidate&&!e.hasSource&&t.push({ruleId:"PUBLISH_MISSING_SOURCE",message:le.PUBLISH_MISSING_SOURCE}),t}function C(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 a=ae({...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:a}),a}function P(e){if(!e||e==="<input>"||e.startsWith("stdin"))return null;let t=p.default.dirname(p.default.resolve(e));for(;;){let n=p.default.join(t,"ark.config.json");if(I.default.existsSync(n))return n;let i=p.default.dirname(t);if(i===t)return null;t=i}}var H=new Map;function j(e){if(H.has(e))return H.get(e)??null;if(!I.default.existsSync(e))return null;let t=oe(I.default.readFileSync(e,"utf8"),e).config;return H.set(e,t),t}function ce(e,t){if(!t.startsWith("."))return null;let n=p.default.resolve(p.default.dirname(e),t),i=[n,`${n}.ts`,`${n}.tsx`,`${n}.mts`,`${n}.cts`,`${n}.js`,`${n}.jsx`,p.default.join(n,"index.ts"),p.default.join(n,"index.tsx"),p.default.join(n,"index.js")];for(let r of i)try{if(I.default.existsSync(r)&&I.default.statSync(r).isFile())return r}catch{}return`${n}.ts`}function v(e){return typeof e?.value=="string"?e.value:void 0}function U(e){return e?.name??v(e)}function q(e){return e.sourceCode??e.getSourceCode?.()}function ue(e,t){let n=q(e)?.getScope?.(t);for(;n;){let i=n.references?.find(r=>r.identifier===t);if(i)return i;n=n.upper??void 0}}function O(e,t,n){let i=ue(e,t);if(i?.resolved)return(i.resolved.defs?.length??0)>0;let r=q(e)?.getScope?.(t);for(;r;){let a=r.set?.get(n);if(a)return(a.defs?.length??0)>0;r=r.upper??void 0}return!1}function Ve(e,t){let n=ue(e,t);return n?n.isValueReference!==!1:t.parent?.type==="VariableDeclarator"&&t.parent.init===t}function de(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=de(e.object),i=U(e.property);if(!(!n||!i))return{root:n.root,segments:[...n.segments,i]}}function Ge(e){return U(e.callee?.property)}function pe(e,t){return e?.properties?.find(n=>U(n.key)===t)}function _(e,t){return pe(e,t)!==void 0}function Ke(e){let t=pe(e,"metadata")?.value;return _(t,"source")}function fe(e){return Ge(e)==="publish"}var ge={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=C(e),n=P(t),i=n?j(n):null,r=n?p.default.dirname(n):null,a=l=>{let c=v(l.source);if(c&&i&&r&&t){let f=p.default.isAbsolute(t)?t:p.default.resolve(t),g=p.default.relative(r,f).split(p.default.sep).join("/"),d=A(g,i.layers);if(!d)return;let o=ce(f,c);if(!o)return;let s=p.default.relative(r,o).split(p.default.sep).join("/");if(s.startsWith(".."))return;let u=A(s,i.layers);if(!u)return;M(i.rules,d,u,{fromPath:g,toPath:s,layers:i.layers})&&w(e,l,"forbiddenImport",{ruleId:"LAYER_IMPORT_VIOLATION",file:g,fromLayer:d,toLayer:u,target:s,...l.importKind==="type"?{typeOnly:!0}:{},message:`${d} must not import ${u}.`},{fromLayer:d,toLayer:u,specifier:c});return}};return{ImportDeclaration:a,ExportNamedDeclaration:a,ExportAllDeclaration:a}}},me={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=v(n),r=B({publishCall:fe(t),rawIntentName:i,objectHasIntent:_(n,"intent"),arkPublishCandidate:!1,hasSource:!0});if(r.some(a=>a.ruleId==="RAW_EVENT_PUBLISH")){let a=r.find(l=>l.ruleId==="RAW_EVENT_PUBLISH");w(e,t,"rawPublish",{...a,file:C(e)})}}}}},ye={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],a=B({publishCall:fe(t),rawIntentName:v(n),objectHasIntent:_(n,"intent"),arkPublishCandidate:!0,hasSource:Ke(n)||_(i,"source")}).find(l=>l.ruleId==="PUBLISH_MISSING_SOURCE");a&&w(e,t,"missingSource",{...a,file:C(e)})}}}},be={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` is a standalone fallback when no project config applies."},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.',forbiddenModule:'{{layer}} must not use module "{{specifier}}" because it is the import form of forbidden global "{{name}}".'},schema:[{type:"object",properties:{globals:{type:"array",items:{type:"string"}}},additionalProperties:!1}]},create(e){let t=C(e),n=e.options?.[0],i=P(t),r=i?j(i):null,a=i?p.default.dirname(i):null,l=null,c="this layer";if(r&&a&&t){let o=p.default.isAbsolute(t)?t:p.default.resolve(t),s=p.default.relative(a,o).split(p.default.sep).join("/"),u=r.layers?.find(m=>m.name===A(s,r.layers));u?.forbiddenGlobals?.length?(l=new Set(u.forbiddenGlobals),c=u.name):l=null}else n?.globals&&(l=new Set(n.globals));if(!l)return{};let f=typeof q(e)?.getScope=="function",g=(o,s)=>{let u=p.default.isAbsolute(t)?t:p.default.resolve(t),m=a?p.default.relative(a,u).split(p.default.sep).join("/"):t;w(e,o,r?"forbiddenGlobal":"forbiddenGlobalDefault",{ruleId:"FORBIDDEN_GLOBAL",file:m,fromLayer:c,target:s,message:`${c} must not use the ambient global "${s}".`},{name:s,layer:c})},d=(o,s,u,m)=>{if(u||typeof s!="string")return;let y=V(s,l);if(!y)return;let R=p.default.isAbsolute(t)?t:p.default.resolve(t),x=a?p.default.relative(a,R).split(p.default.sep).join("/"):t;w(e,o,"forbiddenModule",{ruleId:"FORBIDDEN_GLOBAL",file:x,fromLayer:c,target:s,message:`${c} must not use module "${s}" because it is the import form of forbidden global "${y}".`},{layer:c,name:y,specifier:s,importKind:m})};return{MemberExpression(o){if(o.parent?.type==="MemberExpression"&&o.parent.object===o)return;let s=de(o);if(!s||O(e,s.root,s.segments[0]))return;let u=s.segments[0]==="globalThis",m=u?s.segments.slice(1):s.segments,y;for(let R=m.length;R>=(u?1:2);R-=1){let x=m.slice(0,R).join(".");if(l.has(x)){y=x;break}}y?g(o,y):!f&&l.has(s.segments[0])&&g(o,s.segments[0])},CallExpression(o){let s=o;if(s.callee?.type==="Identifier"&&s.callee.name==="require"&&s.arguments?.[0]?.type==="Literal"&&!O(e,o,"require")&&d(o,s.arguments[0].value,!1,"require"),f)return;let u=s.callee?.type==="Identifier"?s.callee.name:void 0;u&&l.has(u)&&g(o,u)},ImportDeclaration(o){let s=o,u=(s.specifiers??[]).filter(y=>y.type==="ImportSpecifier"),m=u.length>0&&u.length===(s.specifiers??[]).length&&u.every(y=>y.importKind==="type");d(o,s.source?.value,s.importKind==="type"||m,"import")},ImportExpression(o){let s=o;s.source?.type==="Literal"&&d(o,s.source.value,!1,"dynamic-import")},TSImportEqualsDeclaration(o){let s=o;d(o,s.moduleReference?.expression?.value,s.importKind==="type"||s.isTypeOnly===!0,"require")},ExportNamedDeclaration(o){let s=o;if(!s.source)return;let u=s.specifiers??[],m=u.length>0&&u.every(y=>y.exportKind==="type");d(o,s.source.value,s.exportKind==="type"||m,"export")},ExportAllDeclaration(o){let s=o;d(o,s.source?.value,s.exportKind==="type","export")},NewExpression(o){if(f)return;let s=o.callee?.type==="Identifier"?o.callee.name:void 0;s&&l.has(s)&&g(o,s)},Identifier(o){!f||!o.name||!l.has(o.name)||!Ve(e,o)||O(e,o,o.name)||g(o,o.name)}}}},he={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=C(e),n=P(t),i=n?j(n):null,r=n?p.default.dirname(n):null;if(!i||!r||!t)return{};let a=p.default.isAbsolute(t)?t:p.default.resolve(t),l=p.default.relative(r,a).split(p.default.sep).join("/"),c=i.layers?.find(d=>d.name===A(l,i.layers));if(!c)return{};let f=new Set(ee(c));if(f.size===0)return{};let g=(d,o,s)=>{if(s||typeof o!="string"||V(o,c.forbiddenGlobals??[]))return;let u=Q(o);!u||!f.has(u)||w(e,d,"deniedCapability",{ruleId:"CAPABILITY_VIOLATION",file:l,fromLayer:c.name,target:o,capability:u,message:`${c.name} denies the ${u} capability; found import of "${o}".`},{layer:c.name,capability:u,specifier:o})};return{ImportDeclaration(d){let o=d,s=(o.specifiers??[]).filter(m=>m.type==="ImportSpecifier"),u=s.length>0&&s.length===(o.specifiers??[]).length&&s.every(m=>m.importKind==="type");g(d,o.source?.value,o.importKind==="type"||u)},ImportExpression(d){let o=d;o.source?.type==="Literal"&&g(d,o.source.value,!1)},TSImportEqualsDeclaration(d){let o=d;g(d,o.moduleReference?.expression?.value,o.importKind==="type"||o.isTypeOnly===!0)},ExportNamedDeclaration(d){let o=d;if(!o.source)return;let s=o.specifiers??[],u=s.length>0&&s.every(m=>m.exportKind==="type");g(d,o.source.value,o.exportKind==="type"||u)},ExportAllDeclaration(d){let o=d;g(d,o.source?.value,o.exportKind==="type")},CallExpression(d){let o=d;o.callee?.type==="Identifier"&&o.callee.name==="require"&&o.arguments?.[0]?.type==="Literal"&&!O(e,d,"require")&&g(d,o.arguments[0].value,!1)}}}},Be={"no-domain-infra-imports":ge,"no-raw-event-publish":me,"require-publish-source":ye,"no-forbidden-globals":be,"no-denied-capabilities":he},$={rules:Be};$.configs={recommended:{plugins:{ark:$},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 He=$;0&&(module.exports={findConfigPath,globToRegExp,isEdgeDenied,layerForRelativePath,loadArkConfig,noDeniedCapabilities,noDomainInfraImports,noForbiddenGlobals,noRawEventPublish,patternSpecificity,plugin,requirePublishSource,resolveRelativeImport});
@@ -1,3 +1,3 @@
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}):
1
+ import R from"fs";import p from"path";var H=new Map;function U(e){return/[.*+?^${}()|[\]\\]/.test(e)?`\\${e}`:e}function $(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 ue(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 _(e){let t=H.get(e);if(t)return t;let n=$(e),i=ue(n),r="",a=0;for(let c=0;c<n.length;c+=1){let f=n[c];f==="\\"&&c+1<n.length?(r+=U(n[c+1]),c+=1):f==="*"?n[c+1]==="*"?n[c+2]==="/"?(r+="(?:.*/)?",c+=2):(r+=".*",c+=1):r+="[^/]*":f==="?"?r+="[^/]":f==="{"&&i?(r+="(?:",a+=1):f==="}"&&i&&a>0?(r+=")",a-=1):f===","&&i&&a>0?r+="|":r+=U(f)}let l=new RegExp(`^${r}$`);return H.set(e,l),l}function W(e){let t=$(String(e)),i=t.split("*")[0].split("/").filter(Boolean).length,r=t.replace(/\*/g,"").length;return i*1e4+r}function w(e,t){let n=String(e).split(/[/\\]/).join("/"),i,r=-1;for(let a of t??[])if(!(a.exclude??[]).some(l=>_(l).test(n))){for(let l of a.patterns??[])if(_(l).test(n)){let c=W(l);c>r&&(r=c,i=a.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].toLowerCase()}/${n[r+1].toLowerCase()}`}function de(e){let t=new Set;for(let n of e??[]){let r=$(String(n)).split("/").filter(Boolean);for(let a=0;a<r.length;a+=1){let l=r[a];if((l==="**"||l==="*")&&a>0){let c=r[a-1];c&&!c.includes("*")&&!c.includes("{")&&!c.includes("}")&&t.add(c)}}}return[...t]}function pe(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 de(i?.patterns)}function fe(e,t,n,i){for(let r of e??[])if(!(r.from!==t||r.to!==n)&&r.allowed===!1){if(r.peerIsolation){let a=i?.fromPath,l=i?.toPath;if(!a||!l)continue;let c=pe(r,t,i?.layers);if(c.length===0)continue;let f=q(a,c),g=q(l,c);if(!f||!g)continue;if(f!==g)return r;continue}if(t!==n)return r}}function z(e,t,n,i){return fe(e,t,n,i)!==void 0}var Y=Object.freeze(["network","filesystem","clock","randomness","environment","process","persistence"]),ge=Object.freeze({fetch:"network",XMLHttpRequest:"network",Date:"clock","Date.now":"clock","Math.random":"randomness","process.env":"environment",process:"process"}),ve=Object.freeze(Object.keys(ge).sort()),P=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"}),me=Object.freeze({process:Object.freeze(["process","node:process"])});function J(e){if(!e||e.startsWith(".")||e.startsWith("/"))return null;let t=P[e];if(t)return t;let n=e.indexOf("/");if(n<0)return null;let i=e.slice(0,n),r=P[i];if(r)return r;let a=e.indexOf("/",n+1);return a<0?null:P[e.slice(0,a)]??null}function j(e,t){for(let n of t)if(me[n]?.includes(e))return n;return null}function Z(e){if(e?.pure===!0)return[...Y].sort();let n=(e?.capabilities?.deny??[]).filter(i=>Y.includes(i));return[...new Set(n)].sort()}var F="https://unpkg.com/arkgate@2/schemas/ark.config.schema.json",X=["DomainModel","ApplicationOrchestration","PersistenceAdapters","IntegrationAdapters","WorkflowSagaEngine","BackgroundJobsScheduling","PresentationAdapters","ReportingReadModels","ExtensibilityMetadata","SecurityAuditObservability","Kernel"],ye=new Set(["PresentationAdapters->ApplicationOrchestration","ApplicationOrchestration->DomainModel","WorkflowSagaEngine->ApplicationOrchestration","WorkflowSagaEngine->DomainModel","BackgroundJobsScheduling->ApplicationOrchestration"]);function be(){let e=[];for(let t of X)for(let n of X)t===n||ye.has(`${t}->${n}`)||e.push({from:t,to:n,allowed:!1});return e}var ee=be();var h={type:"array",items:{type:"string",minLength:1},uniqueItems:!0},Q={$schema:"https://json-schema.org/draft/2020-12/schema",$id:F,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:F,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:{...h,minItems:1,default:["src"]},exclude:{...h,default:[]},excludeGenerated:{type:"boolean",default:!0},frameworkOverlay:{type:"string",minLength:1},layers:{type:"array",default:[],items:{$ref:"#/$defs/layer"}},rules:{type:"array",default:ee,items:{$ref:"#/$defs/rule"}},cyclePolicy:{type:"string",enum:["strict","soft","framework-soft","off"],default:"strict"},dynamicImportAllowlist:{...h,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:{...h,minItems:1},exclude:h,intentPrefixes:h,description:{type:"string",minLength:1},forbiddenGlobals:h,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:{...h,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 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};
3
+ `)}`),this.name="ArkConfigValidationError",this.source=t,this.issues=n}};function te(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}function v(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 he(e,t){let n="#/$defs/";if(e.startsWith(n))return t.$defs[e.slice(n.length)]}function N(e,t,n,i,r){if(t.$ref){let a=he(t.$ref,i);if(!a){r.push({path:n,message:`schema reference ${t.$ref} cannot be resolved`});return}N(e,a,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(a=>Object.is(a,e))){r.push({path:n,message:`must be one of ${t.enum.map(String).join(", ")}`});return}if(t.type==="object"){if(!te(e)){r.push({path:n,message:`must be an object; received ${A(e)}`});return}let a=t.properties??{};for(let l of t.required??[])e[l]===void 0&&r.push({path:v(n,l),message:"is required"});if(t.additionalProperties===!1)for(let l of Object.keys(e))l in a||r.push({path:v(n,l),message:"unknown field"});for(let[l,c]of Object.entries(a))e[l]!==void 0&&N(e[l],c,v(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 a=e.map(l=>JSON.stringify(l));new Set(a).size!==a.length&&r.push({path:n,message:"must not contain duplicate items"})}t.items&&e.forEach((a,l)=>N(a,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 Ae(e){return{...e,$schema:e.$schema===void 0?F: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?ee.map(t=>({...t})):e.rules}}function ke(e,t="ark.config.json"){if(!te(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:Ae(e),migratedFrom:n}}function Se(e,t="ark.config.json"){let{candidate:n,migratedFrom:i}=ke(e,t),r=[];if(N(n,Q,"$",Q,r),r.length>0)throw new k(t,r);return{config:n,migratedFrom:i}}function ne(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 Se(n,t)}function b(e){return typeof e=="string"&&e.length>0?e:void 0}function re(e,t){return Number.isInteger(e)&&Number(e)>0?Number(e):t}function Ie(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 ${b(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 ie(e,t="error"){let n=b(e.ruleId)??b(e.code)??"ARK_UNKNOWN",i=e.severity==="warning"?"warning":t,r={...b(e.target)?{target:b(e.target)}:{},...b(e.fromLayer)?{fromLayer:b(e.fromLayer)}:{},...b(e.toLayer)?{toLayer:b(e.toLayer)}:{},...typeof e.typeOnly=="boolean"?{typeOnly:e.typeOnly}:{}};return{ruleId:n,severity:i,message:b(e.message)??n,location:{file:b(e.file)??"<unknown>",line:re(e.line,1),column:re(e.column,1)},evidence:r,nextAction:b(e.nextAction)??Ie(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 we(e){return/^(Domain|Application|Adapter|Workflow|Job|Presentation|Reporting|Metadata|Security|Audit|Observability|Kernel)\.[A-Za-z0-9_.]+$/.test(e)}function D(e){if(!e.publishCall)return[];let t=[];return(e.rawIntentName!==void 0&&we(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 C(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 S(e,t,n,i,r){let a=ie({...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:a}),a}function V(e){if(!e||e==="<input>"||e.startsWith("stdin"))return null;let t=p.dirname(p.resolve(e));for(;;){let n=p.join(t,"ark.config.json");if(R.existsSync(n))return n;let i=p.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(!R.existsSync(e))return null;let t=ne(R.readFileSync(e,"utf8"),e).config;return M.set(e,t),t}function Re(e,t){if(!t.startsWith("."))return null;let n=p.resolve(p.dirname(e),t),i=[n,`${n}.ts`,`${n}.tsx`,`${n}.mts`,`${n}.cts`,`${n}.js`,`${n}.jsx`,p.join(n,"index.ts"),p.join(n,"index.tsx"),p.join(n,"index.js")];for(let r of i)try{if(R.existsSync(r)&&R.statSync(r).isFile())return r}catch{}return`${n}.ts`}function O(e){return typeof e?.value=="string"?e.value:void 0}function K(e){return e?.name??O(e)}function B(e){return e.sourceCode??e.getSourceCode?.()}function se(e,t){let n=B(e)?.getScope?.(t);for(;n;){let i=n.references?.find(r=>r.identifier===t);if(i)return i;n=n.upper??void 0}}function E(e,t,n){let i=se(e,t);if(i?.resolved)return(i.resolved.defs?.length??0)>0;let r=B(e)?.getScope?.(t);for(;r;){let a=r.set?.get(n);if(a)return(a.defs?.length??0)>0;r=r.upper??void 0}return!1}function Ce(e,t){let n=se(e,t);return n?n.isValueReference!==!1:t.parent?.type==="VariableDeclarator"&&t.parent.init===t}function ae(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=ae(e.object),i=K(e.property);if(!(!n||!i))return{root:n.root,segments:[...n.segments,i]}}function xe(e){return K(e.callee?.property)}function le(e,t){return e?.properties?.find(n=>K(n.key)===t)}function L(e,t){return le(e,t)!==void 0}function Ne(e){let t=le(e,"metadata")?.value;return L(t,"source")}function ce(e){return xe(e)==="publish"}var Ee={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=C(e),n=V(t),i=n?G(n):null,r=n?p.dirname(n):null,a=l=>{let c=O(l.source);if(c&&i&&r&&t){let f=p.isAbsolute(t)?t:p.resolve(t),g=p.relative(r,f).split(p.sep).join("/"),d=w(g,i.layers);if(!d)return;let o=Re(f,c);if(!o)return;let s=p.relative(r,o).split(p.sep).join("/");if(s.startsWith(".."))return;let u=w(s,i.layers);if(!u)return;z(i.rules,d,u,{fromPath:g,toPath:s,layers:i.layers})&&S(e,l,"forbiddenImport",{ruleId:"LAYER_IMPORT_VIOLATION",file:g,fromLayer:d,toLayer:u,target:s,...l.importKind==="type"?{typeOnly:!0}:{},message:`${d} must not import ${u}.`},{fromLayer:d,toLayer:u,specifier:c});return}};return{ImportDeclaration:a,ExportNamedDeclaration:a,ExportAllDeclaration:a}}},Le={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=D({publishCall:ce(t),rawIntentName:i,objectHasIntent:L(n,"intent"),arkPublishCandidate:!1,hasSource:!0});if(r.some(a=>a.ruleId==="RAW_EVENT_PUBLISH")){let a=r.find(l=>l.ruleId==="RAW_EVENT_PUBLISH");S(e,t,"rawPublish",{...a,file:C(e)})}}}}},Oe={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],a=D({publishCall:ce(t),rawIntentName:O(n),objectHasIntent:L(n,"intent"),arkPublishCandidate:!0,hasSource:Ne(n)||L(i,"source")}).find(l=>l.ruleId==="PUBLISH_MISSING_SOURCE");a&&S(e,t,"missingSource",{...a,file:C(e)})}}}},_e={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` is a standalone fallback when no project config applies."},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.',forbiddenModule:'{{layer}} must not use module "{{specifier}}" because it is the import form of forbidden global "{{name}}".'},schema:[{type:"object",properties:{globals:{type:"array",items:{type:"string"}}},additionalProperties:!1}]},create(e){let t=C(e),n=e.options?.[0],i=V(t),r=i?G(i):null,a=i?p.dirname(i):null,l=null,c="this layer";if(r&&a&&t){let o=p.isAbsolute(t)?t:p.resolve(t),s=p.relative(a,o).split(p.sep).join("/"),u=r.layers?.find(m=>m.name===w(s,r.layers));u?.forbiddenGlobals?.length?(l=new Set(u.forbiddenGlobals),c=u.name):l=null}else n?.globals&&(l=new Set(n.globals));if(!l)return{};let f=typeof B(e)?.getScope=="function",g=(o,s)=>{let u=p.isAbsolute(t)?t:p.resolve(t),m=a?p.relative(a,u).split(p.sep).join("/"):t;S(e,o,r?"forbiddenGlobal":"forbiddenGlobalDefault",{ruleId:"FORBIDDEN_GLOBAL",file:m,fromLayer:c,target:s,message:`${c} must not use the ambient global "${s}".`},{name:s,layer:c})},d=(o,s,u,m)=>{if(u||typeof s!="string")return;let y=j(s,l);if(!y)return;let I=p.isAbsolute(t)?t:p.resolve(t),x=a?p.relative(a,I).split(p.sep).join("/"):t;S(e,o,"forbiddenModule",{ruleId:"FORBIDDEN_GLOBAL",file:x,fromLayer:c,target:s,message:`${c} must not use module "${s}" because it is the import form of forbidden global "${y}".`},{layer:c,name:y,specifier:s,importKind:m})};return{MemberExpression(o){if(o.parent?.type==="MemberExpression"&&o.parent.object===o)return;let s=ae(o);if(!s||E(e,s.root,s.segments[0]))return;let u=s.segments[0]==="globalThis",m=u?s.segments.slice(1):s.segments,y;for(let I=m.length;I>=(u?1:2);I-=1){let x=m.slice(0,I).join(".");if(l.has(x)){y=x;break}}y?g(o,y):!f&&l.has(s.segments[0])&&g(o,s.segments[0])},CallExpression(o){let s=o;if(s.callee?.type==="Identifier"&&s.callee.name==="require"&&s.arguments?.[0]?.type==="Literal"&&!E(e,o,"require")&&d(o,s.arguments[0].value,!1,"require"),f)return;let u=s.callee?.type==="Identifier"?s.callee.name:void 0;u&&l.has(u)&&g(o,u)},ImportDeclaration(o){let s=o,u=(s.specifiers??[]).filter(y=>y.type==="ImportSpecifier"),m=u.length>0&&u.length===(s.specifiers??[]).length&&u.every(y=>y.importKind==="type");d(o,s.source?.value,s.importKind==="type"||m,"import")},ImportExpression(o){let s=o;s.source?.type==="Literal"&&d(o,s.source.value,!1,"dynamic-import")},TSImportEqualsDeclaration(o){let s=o;d(o,s.moduleReference?.expression?.value,s.importKind==="type"||s.isTypeOnly===!0,"require")},ExportNamedDeclaration(o){let s=o;if(!s.source)return;let u=s.specifiers??[],m=u.length>0&&u.every(y=>y.exportKind==="type");d(o,s.source.value,s.exportKind==="type"||m,"export")},ExportAllDeclaration(o){let s=o;d(o,s.source?.value,s.exportKind==="type","export")},NewExpression(o){if(f)return;let s=o.callee?.type==="Identifier"?o.callee.name:void 0;s&&l.has(s)&&g(o,s)},Identifier(o){!f||!o.name||!l.has(o.name)||!Ce(e,o)||E(e,o,o.name)||g(o,o.name)}}}},$e={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=C(e),n=V(t),i=n?G(n):null,r=n?p.dirname(n):null;if(!i||!r||!t)return{};let a=p.isAbsolute(t)?t:p.resolve(t),l=p.relative(r,a).split(p.sep).join("/"),c=i.layers?.find(d=>d.name===w(l,i.layers));if(!c)return{};let f=new Set(Z(c));if(f.size===0)return{};let g=(d,o,s)=>{if(s||typeof o!="string"||j(o,c.forbiddenGlobals??[]))return;let u=J(o);!u||!f.has(u)||S(e,d,"deniedCapability",{ruleId:"CAPABILITY_VIOLATION",file:l,fromLayer:c.name,target:o,capability:u,message:`${c.name} denies the ${u} capability; found import of "${o}".`},{layer:c.name,capability:u,specifier:o})};return{ImportDeclaration(d){let o=d,s=(o.specifiers??[]).filter(m=>m.type==="ImportSpecifier"),u=s.length>0&&s.length===(o.specifiers??[]).length&&s.every(m=>m.importKind==="type");g(d,o.source?.value,o.importKind==="type"||u)},ImportExpression(d){let o=d;o.source?.type==="Literal"&&g(d,o.source.value,!1)},TSImportEqualsDeclaration(d){let o=d;g(d,o.moduleReference?.expression?.value,o.importKind==="type"||o.isTypeOnly===!0)},ExportNamedDeclaration(d){let o=d;if(!o.source)return;let s=o.specifiers??[],u=s.length>0&&s.every(m=>m.exportKind==="type");g(d,o.source.value,o.exportKind==="type"||u)},ExportAllDeclaration(d){let o=d;g(d,o.source?.value,o.exportKind==="type")},CallExpression(d){let o=d;o.callee?.type==="Identifier"&&o.callee.name==="require"&&o.arguments?.[0]?.type==="Literal"&&!E(e,d,"require")&&g(d,o.arguments[0].value,!1)}}}},Pe={"no-domain-infra-imports":Ee,"no-raw-event-publish":Le,"require-publish-source":Oe,"no-forbidden-globals":_e,"no-denied-capabilities":$e},T={rules:Pe};T.configs={recommended:{plugins:{ark:T},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 We=T;export{We as default,V as findConfigPath,_ as globToRegExp,z as isEdgeDenied,w as layerForRelativePath,G as loadArkConfig,$e as noDeniedCapabilities,Ee as noDomainInfraImports,_e as noForbiddenGlobals,Le as noRawEventPublish,W as patternSpecificity,T as plugin,Oe as requirePublishSource,Re as resolveRelativeImport};