@kernlang/review 3.1.1 → 3.1.3
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.
- package/README.md +4 -1
- package/dist/concept-rules/index.js +0 -2
- package/dist/concept-rules/index.js.map +1 -1
- package/dist/concept-rules/unrecovered-effect.js +2 -1
- package/dist/concept-rules/unrecovered-effect.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +76 -4
- package/dist/index.js.map +1 -1
- package/dist/kern-lint.d.ts +9 -3
- package/dist/kern-lint.js +22 -3
- package/dist/kern-lint.js.map +1 -1
- package/dist/llm-bridge.js +53 -6
- package/dist/llm-bridge.js.map +1 -1
- package/dist/llm-review.js +6 -9
- package/dist/llm-review.js.map +1 -1
- package/dist/mappers/ts-concepts.js +190 -8
- package/dist/mappers/ts-concepts.js.map +1 -1
- package/dist/reporter.js +7 -4
- package/dist/reporter.js.map +1 -1
- package/dist/rule-eval.d.ts +81 -0
- package/dist/rule-eval.js +449 -0
- package/dist/rule-eval.js.map +1 -0
- package/dist/rule-loader.d.ts +17 -0
- package/dist/rule-loader.js +155 -0
- package/dist/rule-loader.js.map +1 -0
- package/dist/rules/base.js +32 -10
- package/dist/rules/base.js.map +1 -1
- package/dist/rules/null-safety.js +9 -7
- package/dist/rules/null-safety.js.map +1 -1
- package/dist/rules/react.js +45 -17
- package/dist/rules/react.js.map +1 -1
- package/dist/rules/security-v3.d.ts +6 -0
- package/dist/rules/security-v3.js +13 -6
- package/dist/rules/security-v3.js.map +1 -1
- package/dist/taint.js +41 -12
- package/dist/taint.js.map +1 -1
- package/dist/types.d.ts +14 -2
- package/dist/types.js +3 -7
- package/dist/types.js.map +1 -1
- package/package.json +11 -2
|
@@ -0,0 +1,449 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* KERN Native Rule Evaluation Engine
|
|
3
|
+
*
|
|
4
|
+
* Evaluates .kern rule definitions against IR node trees.
|
|
5
|
+
* Rules use pattern/guard/expect/message nodes (all existing KERN types)
|
|
6
|
+
* under a `rule` root node.
|
|
7
|
+
*/
|
|
8
|
+
import { createFingerprint } from './types.js';
|
|
9
|
+
// ── Concept → IR Wrapper ────────────────────────────────────────────────
|
|
10
|
+
/** Flatten a concept payload into plain props (skip 'kind' — it becomes node type). */
|
|
11
|
+
function flattenPayload(payload) {
|
|
12
|
+
const flat = {};
|
|
13
|
+
for (const [k, v] of Object.entries(payload)) {
|
|
14
|
+
if (k === 'kind')
|
|
15
|
+
continue;
|
|
16
|
+
flat[k] = v;
|
|
17
|
+
}
|
|
18
|
+
return flat;
|
|
19
|
+
}
|
|
20
|
+
function countUpLevels(specifier) {
|
|
21
|
+
const match = specifier.match(/^(\.\.\/)+/);
|
|
22
|
+
if (!match)
|
|
23
|
+
return 0;
|
|
24
|
+
return match[0].length / 3;
|
|
25
|
+
}
|
|
26
|
+
/** Convert a ConceptNode to an IRNode-shaped wrapper for the pattern matcher. */
|
|
27
|
+
export function conceptNodeToIR(concept) {
|
|
28
|
+
const props = {
|
|
29
|
+
...flattenPayload(concept.payload),
|
|
30
|
+
// Metadata after payload — metadata always wins on collision
|
|
31
|
+
_concept: true,
|
|
32
|
+
evidence: concept.evidence,
|
|
33
|
+
confidence: concept.confidence,
|
|
34
|
+
language: concept.language,
|
|
35
|
+
};
|
|
36
|
+
if (concept.containerId)
|
|
37
|
+
props.containerId = concept.containerId;
|
|
38
|
+
return {
|
|
39
|
+
type: concept.kind,
|
|
40
|
+
loc: {
|
|
41
|
+
line: concept.primarySpan.startLine,
|
|
42
|
+
col: concept.primarySpan.startCol,
|
|
43
|
+
endLine: concept.primarySpan.endLine,
|
|
44
|
+
endCol: concept.primarySpan.endCol,
|
|
45
|
+
},
|
|
46
|
+
props,
|
|
47
|
+
children: [],
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
/** Convert a ConceptEdge to an IRNode-shaped wrapper for the pattern matcher. */
|
|
51
|
+
export function conceptEdgeToIR(edge) {
|
|
52
|
+
const props = {
|
|
53
|
+
...flattenPayload(edge.payload),
|
|
54
|
+
_concept: true,
|
|
55
|
+
_edge: true,
|
|
56
|
+
sourceId: edge.sourceId,
|
|
57
|
+
targetId: edge.targetId,
|
|
58
|
+
evidence: edge.evidence,
|
|
59
|
+
confidence: edge.confidence,
|
|
60
|
+
language: edge.language,
|
|
61
|
+
};
|
|
62
|
+
if ('specifier' in edge.payload && typeof edge.payload.specifier === 'string') {
|
|
63
|
+
props.upLevels = countUpLevels(edge.payload.specifier);
|
|
64
|
+
}
|
|
65
|
+
return {
|
|
66
|
+
type: edge.kind,
|
|
67
|
+
loc: {
|
|
68
|
+
line: edge.primarySpan.startLine,
|
|
69
|
+
col: edge.primarySpan.startCol,
|
|
70
|
+
endLine: edge.primarySpan.endLine,
|
|
71
|
+
endCol: edge.primarySpan.endCol,
|
|
72
|
+
},
|
|
73
|
+
props,
|
|
74
|
+
children: [],
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
/** Build a rule index from a list of IR nodes, optionally including concept nodes and edges. */
|
|
78
|
+
export function buildRuleIndex(nodes, concepts) {
|
|
79
|
+
const nodesByType = new Map();
|
|
80
|
+
const parentMap = new Map();
|
|
81
|
+
const allNodes = [];
|
|
82
|
+
function walk(node, parent) {
|
|
83
|
+
allNodes.push(node);
|
|
84
|
+
parentMap.set(node, parent);
|
|
85
|
+
const list = nodesByType.get(node.type);
|
|
86
|
+
if (list)
|
|
87
|
+
list.push(node);
|
|
88
|
+
else
|
|
89
|
+
nodesByType.set(node.type, [node]);
|
|
90
|
+
for (const child of node.children || []) {
|
|
91
|
+
walk(child, node);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
for (const node of nodes)
|
|
95
|
+
walk(node);
|
|
96
|
+
// Add concept nodes and edges as flat IRNode wrappers (no parent, no children)
|
|
97
|
+
if (concepts) {
|
|
98
|
+
for (const cn of concepts.nodes) {
|
|
99
|
+
walk(conceptNodeToIR(cn));
|
|
100
|
+
}
|
|
101
|
+
for (const ce of concepts.edges) {
|
|
102
|
+
walk(conceptEdgeToIR(ce));
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
// Build peer index — index nodes by prop values for peer-scoped guards
|
|
106
|
+
const peerIndex = new Map();
|
|
107
|
+
for (const node of allNodes) {
|
|
108
|
+
const np = node.props || {};
|
|
109
|
+
for (const [field, val] of Object.entries(np)) {
|
|
110
|
+
if (typeof val !== 'string' || field.startsWith('_'))
|
|
111
|
+
continue;
|
|
112
|
+
let fieldMap = peerIndex.get(field);
|
|
113
|
+
if (!fieldMap) {
|
|
114
|
+
fieldMap = new Map();
|
|
115
|
+
peerIndex.set(field, fieldMap);
|
|
116
|
+
}
|
|
117
|
+
let list = fieldMap.get(val);
|
|
118
|
+
if (!list) {
|
|
119
|
+
list = [];
|
|
120
|
+
fieldMap.set(val, list);
|
|
121
|
+
}
|
|
122
|
+
list.push(node);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
return { nodesByType, parentMap, allNodes, peerIndex };
|
|
126
|
+
}
|
|
127
|
+
const NO_MATCH = { matched: false, bindings: new Map() };
|
|
128
|
+
/** Get props from a node safely. */
|
|
129
|
+
function p(node) {
|
|
130
|
+
return node.props || {};
|
|
131
|
+
}
|
|
132
|
+
/** Get children of a specific type. */
|
|
133
|
+
function childrenOf(node, type) {
|
|
134
|
+
const c = node.children || [];
|
|
135
|
+
return type ? c.filter(n => n.type === type) : c;
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Match a pattern node against a target node.
|
|
139
|
+
*
|
|
140
|
+
* Pattern props:
|
|
141
|
+
* - type=X: target must have this type
|
|
142
|
+
* - prop=X: target must have this prop defined
|
|
143
|
+
* - Any other prop: target must have matching prop value
|
|
144
|
+
*
|
|
145
|
+
* Pattern children:
|
|
146
|
+
* - guard: evaluated as a guard clause
|
|
147
|
+
* - expect: evaluated as a quantifier
|
|
148
|
+
* - Nested pattern: matched recursively against target's children
|
|
149
|
+
*/
|
|
150
|
+
export function matchPattern(pattern, target, index) {
|
|
151
|
+
const pp = p(pattern);
|
|
152
|
+
const tp = p(target);
|
|
153
|
+
const bindings = new Map();
|
|
154
|
+
// Subject filtering — concept nodes isolated from IR nodes
|
|
155
|
+
// subject=concept → only concept nodes; anything else → only IR nodes
|
|
156
|
+
const subject = pp.subject;
|
|
157
|
+
const isConcept = tp._concept === true;
|
|
158
|
+
if (subject === 'concept' && !isConcept)
|
|
159
|
+
return NO_MATCH;
|
|
160
|
+
if (subject !== 'concept' && isConcept)
|
|
161
|
+
return NO_MATCH;
|
|
162
|
+
// Type check
|
|
163
|
+
if (pp.type && pp.type !== target.type)
|
|
164
|
+
return NO_MATCH;
|
|
165
|
+
// Prop existence check (prop=X means "target must have prop X")
|
|
166
|
+
if (pp.prop) {
|
|
167
|
+
const propName = pp.prop;
|
|
168
|
+
if (tp[propName] === undefined)
|
|
169
|
+
return NO_MATCH;
|
|
170
|
+
}
|
|
171
|
+
// Direct prop value matching (name=value checks target.props.name === value)
|
|
172
|
+
// Supports pipe-separated OR: subtype=auth|validation matches either
|
|
173
|
+
for (const [key, val] of Object.entries(pp)) {
|
|
174
|
+
if (['type', 'prop', 'subject', 'not'].includes(key))
|
|
175
|
+
continue;
|
|
176
|
+
if (key.startsWith('min-') || key.startsWith('max-')) {
|
|
177
|
+
const propName = key.slice(4);
|
|
178
|
+
const targetNum = Number(tp[propName]);
|
|
179
|
+
const bound = Number(val);
|
|
180
|
+
if (propName.length === 0 || Number.isNaN(targetNum) || Number.isNaN(bound))
|
|
181
|
+
return NO_MATCH;
|
|
182
|
+
if (key.startsWith('min-') && targetNum < bound)
|
|
183
|
+
return NO_MATCH;
|
|
184
|
+
if (key.startsWith('max-') && targetNum > bound)
|
|
185
|
+
return NO_MATCH;
|
|
186
|
+
continue;
|
|
187
|
+
}
|
|
188
|
+
if (tp[key] === undefined)
|
|
189
|
+
continue;
|
|
190
|
+
const strVal = String(val);
|
|
191
|
+
const targetVal = String(tp[key]);
|
|
192
|
+
if (strVal.includes('|')) {
|
|
193
|
+
const alternatives = strVal.split('|');
|
|
194
|
+
if (!alternatives.includes(targetVal))
|
|
195
|
+
return NO_MATCH;
|
|
196
|
+
}
|
|
197
|
+
else {
|
|
198
|
+
if (targetVal !== strVal)
|
|
199
|
+
return NO_MATCH;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
// Capture all target props as bindings for message interpolation
|
|
203
|
+
for (const [key, val] of Object.entries(tp)) {
|
|
204
|
+
bindings.set(key, val);
|
|
205
|
+
}
|
|
206
|
+
bindings.set('type', target.type);
|
|
207
|
+
// Evaluate child guard nodes
|
|
208
|
+
for (const guard of childrenOf(pattern, 'guard')) {
|
|
209
|
+
if (!evaluateGuard(guard, target, index))
|
|
210
|
+
return NO_MATCH;
|
|
211
|
+
}
|
|
212
|
+
// Evaluate child expect nodes
|
|
213
|
+
for (const expect of childrenOf(pattern, 'expect')) {
|
|
214
|
+
if (!evaluateExpect(expect, target))
|
|
215
|
+
return NO_MATCH;
|
|
216
|
+
}
|
|
217
|
+
// Evaluate nested pattern children (match against target's children)
|
|
218
|
+
for (const subPattern of childrenOf(pattern, 'pattern')) {
|
|
219
|
+
const subPp = p(subPattern);
|
|
220
|
+
const matchType = subPp.type;
|
|
221
|
+
const targetChildren = matchType
|
|
222
|
+
? childrenOf(target, matchType)
|
|
223
|
+
: (target.children || []);
|
|
224
|
+
let anyMatch = false;
|
|
225
|
+
for (const child of targetChildren) {
|
|
226
|
+
const result = matchPattern(subPattern, child, index);
|
|
227
|
+
if (result.matched) {
|
|
228
|
+
anyMatch = true;
|
|
229
|
+
for (const [k, v] of result.bindings)
|
|
230
|
+
bindings.set(k, v);
|
|
231
|
+
break;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
if (!anyMatch)
|
|
235
|
+
return NO_MATCH;
|
|
236
|
+
}
|
|
237
|
+
return { matched: true, bindings };
|
|
238
|
+
}
|
|
239
|
+
// ── Guard Evaluation ────────────────────────────────────────────────────
|
|
240
|
+
/**
|
|
241
|
+
* Evaluate a guard clause against a target node.
|
|
242
|
+
*
|
|
243
|
+
* Guard props:
|
|
244
|
+
* - not=true: negate the result
|
|
245
|
+
* - prop=X: check if target has prop X (negated: check target does NOT have prop X)
|
|
246
|
+
* - scope=X: check if any ancestor has type X
|
|
247
|
+
* - peer=X: check if any node sharing the same value of prop X matches child patterns
|
|
248
|
+
*
|
|
249
|
+
* Guard children:
|
|
250
|
+
* - pattern: must match against target (negated: must NOT match)
|
|
251
|
+
* When peer=X is set, child patterns match against peer nodes instead of target
|
|
252
|
+
*/
|
|
253
|
+
export function evaluateGuard(guard, target, index) {
|
|
254
|
+
const gp = p(guard);
|
|
255
|
+
const isNegated = gp.not === 'true' || gp.not === true;
|
|
256
|
+
let result = true;
|
|
257
|
+
// Prop existence check
|
|
258
|
+
if (gp.prop) {
|
|
259
|
+
const propName = gp.prop;
|
|
260
|
+
const tp = p(target);
|
|
261
|
+
if (tp[propName] === undefined)
|
|
262
|
+
result = false;
|
|
263
|
+
}
|
|
264
|
+
// Scope check — walk ancestor chain (AND-combined with prop check)
|
|
265
|
+
if (result && gp.scope) {
|
|
266
|
+
const scopeType = gp.scope;
|
|
267
|
+
let current = index.parentMap.get(target);
|
|
268
|
+
let found = false;
|
|
269
|
+
while (current) {
|
|
270
|
+
if (current.type === scopeType) {
|
|
271
|
+
found = true;
|
|
272
|
+
break;
|
|
273
|
+
}
|
|
274
|
+
current = index.parentMap.get(current);
|
|
275
|
+
}
|
|
276
|
+
if (!found)
|
|
277
|
+
result = false;
|
|
278
|
+
}
|
|
279
|
+
// Peer check — find nodes sharing the same prop value, match child patterns against them
|
|
280
|
+
if (result && gp.peer) {
|
|
281
|
+
const peerField = gp.peer;
|
|
282
|
+
const targetValue = p(target)[peerField];
|
|
283
|
+
if (!targetValue || typeof targetValue !== 'string') {
|
|
284
|
+
result = false;
|
|
285
|
+
}
|
|
286
|
+
else {
|
|
287
|
+
const peerPatterns = childrenOf(guard, 'pattern');
|
|
288
|
+
if (peerPatterns.length > 0) {
|
|
289
|
+
const fieldMap = index.peerIndex.get(peerField);
|
|
290
|
+
const peers = fieldMap?.get(targetValue) || [];
|
|
291
|
+
let anyPeerMatch = false;
|
|
292
|
+
for (const peer of peers) {
|
|
293
|
+
if (peer === target)
|
|
294
|
+
continue; // skip self
|
|
295
|
+
let allMatch = true;
|
|
296
|
+
for (const pp of peerPatterns) {
|
|
297
|
+
if (!matchPattern(pp, peer, index).matched) {
|
|
298
|
+
allMatch = false;
|
|
299
|
+
break;
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
if (allMatch) {
|
|
303
|
+
anyPeerMatch = true;
|
|
304
|
+
break;
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
result = anyPeerMatch;
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
else {
|
|
312
|
+
// Child pattern matching (non-peer: match against target itself)
|
|
313
|
+
for (const subPattern of childrenOf(guard, 'pattern')) {
|
|
314
|
+
const subResult = matchPattern(subPattern, target, index);
|
|
315
|
+
if (!subResult.matched) {
|
|
316
|
+
result = false;
|
|
317
|
+
break;
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
return isNegated ? !result : result;
|
|
322
|
+
}
|
|
323
|
+
// ── Expect Evaluation ───────────────────────────────────────────────────
|
|
324
|
+
/**
|
|
325
|
+
* Evaluate a quantifier (expect node) against a target node.
|
|
326
|
+
*
|
|
327
|
+
* Expect props:
|
|
328
|
+
* - child-type=X: count children of type X
|
|
329
|
+
* - min=N: require at least N matching children
|
|
330
|
+
* - max=N: require at most N matching children
|
|
331
|
+
* - exact=N: require exactly N matching children
|
|
332
|
+
*/
|
|
333
|
+
export function evaluateExpect(expect, target) {
|
|
334
|
+
const ep = p(expect);
|
|
335
|
+
const childType = ep['child-type'];
|
|
336
|
+
const matching = childType ? childrenOf(target, childType) : (target.children || []);
|
|
337
|
+
const count = matching.length;
|
|
338
|
+
const min = ep.min !== undefined ? Number(ep.min) : undefined;
|
|
339
|
+
const max = ep.max !== undefined ? Number(ep.max) : undefined;
|
|
340
|
+
const exact = ep.exact !== undefined ? Number(ep.exact) : undefined;
|
|
341
|
+
if (min !== undefined && !Number.isNaN(min) && count < min)
|
|
342
|
+
return false;
|
|
343
|
+
if (max !== undefined && !Number.isNaN(max) && count > max)
|
|
344
|
+
return false;
|
|
345
|
+
if (exact !== undefined && !Number.isNaN(exact) && count !== exact)
|
|
346
|
+
return false;
|
|
347
|
+
return true;
|
|
348
|
+
}
|
|
349
|
+
// ── Message Interpolation ───────────────────────────────────────────────
|
|
350
|
+
/**
|
|
351
|
+
* Interpolate {{prop}} placeholders in a message template.
|
|
352
|
+
*/
|
|
353
|
+
export function interpolateMessage(template, bindings) {
|
|
354
|
+
return template.replace(/\{\{([\w-]+)\}\}/g, (_match, key) => {
|
|
355
|
+
const val = bindings.get(key);
|
|
356
|
+
return val !== undefined ? String(val) : `{{${key}}}`;
|
|
357
|
+
});
|
|
358
|
+
}
|
|
359
|
+
// ── Fix Action Construction ─────────────────────────────────────────────
|
|
360
|
+
/**
|
|
361
|
+
* Build a FixAction from a fix node (body child with multiline code).
|
|
362
|
+
*/
|
|
363
|
+
function buildFixAction(fixNode, target, bindings) {
|
|
364
|
+
const fp = p(fixNode);
|
|
365
|
+
const op = fp.op || 'insert-after';
|
|
366
|
+
const bodyNode = childrenOf(fixNode, 'body')[0];
|
|
367
|
+
const code = bodyNode ? (p(bodyNode).code || '') : '';
|
|
368
|
+
if (!code)
|
|
369
|
+
return undefined;
|
|
370
|
+
const replacement = interpolateMessage(code, bindings);
|
|
371
|
+
const span = {
|
|
372
|
+
file: '',
|
|
373
|
+
startLine: target.loc?.line ?? 0,
|
|
374
|
+
startCol: target.loc?.col ?? 0,
|
|
375
|
+
endLine: target.loc?.endLine ?? target.loc?.line ?? 0,
|
|
376
|
+
endCol: target.loc?.endCol ?? target.loc?.col ?? 0,
|
|
377
|
+
};
|
|
378
|
+
return {
|
|
379
|
+
type: op,
|
|
380
|
+
span,
|
|
381
|
+
replacement,
|
|
382
|
+
description: fp.description || `Apply ${op} fix`,
|
|
383
|
+
};
|
|
384
|
+
}
|
|
385
|
+
// ── Rule Evaluation ─────────────────────────────────────────────────────
|
|
386
|
+
/**
|
|
387
|
+
* Evaluate a single native KERN rule against an indexed IR tree.
|
|
388
|
+
* Returns findings for all matched nodes.
|
|
389
|
+
* When concepts are provided, concept nodes are included in the index
|
|
390
|
+
* and accessible via `subject=concept` in pattern nodes.
|
|
391
|
+
*/
|
|
392
|
+
export function evaluateRule(rule, index, filePath) {
|
|
393
|
+
const rp = p(rule);
|
|
394
|
+
const ruleId = rp.id || 'unnamed-rule';
|
|
395
|
+
const severity = rp.severity || 'warning';
|
|
396
|
+
const category = rp.category || 'pattern';
|
|
397
|
+
const confidence = rp.confidence !== undefined ? Number(rp.confidence) : undefined;
|
|
398
|
+
// Get the pattern node
|
|
399
|
+
const patternNode = childrenOf(rule, 'pattern')[0];
|
|
400
|
+
if (!patternNode)
|
|
401
|
+
return [];
|
|
402
|
+
// Get the message template
|
|
403
|
+
const messageNode = childrenOf(rule, 'message')[0];
|
|
404
|
+
const template = messageNode ? p(messageNode).template || '' : ruleId;
|
|
405
|
+
// Get optional fix node
|
|
406
|
+
const fixNode = childrenOf(rule, 'fix')[0];
|
|
407
|
+
// Determine which nodes to check based on pattern type
|
|
408
|
+
const patternType = p(patternNode).type;
|
|
409
|
+
const candidates = patternType
|
|
410
|
+
? (index.nodesByType.get(patternType) || [])
|
|
411
|
+
: index.allNodes;
|
|
412
|
+
const findings = [];
|
|
413
|
+
for (const target of candidates) {
|
|
414
|
+
const result = matchPattern(patternNode, target, index);
|
|
415
|
+
if (!result.matched)
|
|
416
|
+
continue;
|
|
417
|
+
const message = interpolateMessage(template, result.bindings);
|
|
418
|
+
const line = target.loc?.line ?? 0;
|
|
419
|
+
const col = target.loc?.col ?? 1;
|
|
420
|
+
const finding = {
|
|
421
|
+
source: 'kern-native',
|
|
422
|
+
ruleId,
|
|
423
|
+
severity,
|
|
424
|
+
category,
|
|
425
|
+
message,
|
|
426
|
+
primarySpan: {
|
|
427
|
+
file: filePath,
|
|
428
|
+
startLine: line,
|
|
429
|
+
startCol: col,
|
|
430
|
+
endLine: target.loc?.endLine ?? line,
|
|
431
|
+
endCol: target.loc?.endCol ?? col,
|
|
432
|
+
},
|
|
433
|
+
fingerprint: createFingerprint(ruleId, line, col),
|
|
434
|
+
};
|
|
435
|
+
if (confidence !== undefined)
|
|
436
|
+
finding.confidence = confidence;
|
|
437
|
+
// Build autofix if fix node exists
|
|
438
|
+
if (fixNode) {
|
|
439
|
+
const action = buildFixAction(fixNode, target, result.bindings);
|
|
440
|
+
if (action) {
|
|
441
|
+
action.span.file = filePath;
|
|
442
|
+
finding.autofix = action;
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
findings.push(finding);
|
|
446
|
+
}
|
|
447
|
+
return findings;
|
|
448
|
+
}
|
|
449
|
+
//# sourceMappingURL=rule-eval.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rule-eval.js","sourceRoot":"","sources":["../src/rule-eval.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* KERN Native Rule Loader
|
|
3
|
+
*
|
|
4
|
+
* Discovers .kern rule files, parses them, validates structure,
|
|
5
|
+
* and wraps each rule in a KernLintRule adapter for the existing pipeline.
|
|
6
|
+
*/
|
|
7
|
+
import type { KernLintRule } from './kern-lint.js';
|
|
8
|
+
/**
|
|
9
|
+
* Load native .kern rule files from a directory.
|
|
10
|
+
* Returns KernLintRule adapters for all valid rules found.
|
|
11
|
+
* Supports `import from="other.kern"` for rule composition.
|
|
12
|
+
*/
|
|
13
|
+
export declare function loadNativeRules(dirs: string[], skipIds?: Set<string>): KernLintRule[];
|
|
14
|
+
/**
|
|
15
|
+
* Load native rules from the built-in rules directory.
|
|
16
|
+
*/
|
|
17
|
+
export declare function loadBuiltinNativeRules(): KernLintRule[];
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* KERN Native Rule Loader
|
|
3
|
+
*
|
|
4
|
+
* Discovers .kern rule files, parses them, validates structure,
|
|
5
|
+
* and wraps each rule in a KernLintRule adapter for the existing pipeline.
|
|
6
|
+
*/
|
|
7
|
+
import { readFileSync, existsSync, readdirSync, realpathSync } from 'fs';
|
|
8
|
+
import { resolve, join, dirname } from 'path';
|
|
9
|
+
import { fileURLToPath } from 'url';
|
|
10
|
+
import { parseDocument } from '@kernlang/core';
|
|
11
|
+
import { buildRuleIndex, evaluateRule } from './rule-eval.js';
|
|
12
|
+
// ── Validation ──────────────────────────────────────────────────────────
|
|
13
|
+
/** Validate that a rule node has the required structure. */
|
|
14
|
+
function validateRule(rule) {
|
|
15
|
+
const errors = [];
|
|
16
|
+
const rp = rule.props || {};
|
|
17
|
+
const children = rule.children || [];
|
|
18
|
+
if (!rp.id)
|
|
19
|
+
errors.push('Rule missing id prop');
|
|
20
|
+
const hasPattern = children.some(c => c.type === 'pattern');
|
|
21
|
+
if (!hasPattern)
|
|
22
|
+
errors.push('Rule missing pattern child');
|
|
23
|
+
const hasMessage = children.some(c => c.type === 'message');
|
|
24
|
+
if (!hasMessage)
|
|
25
|
+
errors.push('Rule missing message child');
|
|
26
|
+
// Validate severity if present
|
|
27
|
+
if (rp.severity && !['error', 'warning', 'info'].includes(rp.severity)) {
|
|
28
|
+
errors.push(`Invalid severity: ${rp.severity}`);
|
|
29
|
+
}
|
|
30
|
+
// Validate category if present
|
|
31
|
+
if (rp.category && !['bug', 'type', 'pattern', 'style', 'structure'].includes(rp.category)) {
|
|
32
|
+
errors.push(`Invalid category: ${rp.category}`);
|
|
33
|
+
}
|
|
34
|
+
return errors;
|
|
35
|
+
}
|
|
36
|
+
// ── Rule Adapter ────────────────────────────────────────────────────────
|
|
37
|
+
/**
|
|
38
|
+
* Wrap a parsed rule IRNode into a KernLintRule function.
|
|
39
|
+
* The adapter builds a RuleIndex from the target nodes and evaluates the rule.
|
|
40
|
+
* When concepts are provided, concept nodes are included in the index.
|
|
41
|
+
*/
|
|
42
|
+
function nativeRuleAdapter(ruleNode) {
|
|
43
|
+
const ruleId = ruleNode.props?.id || 'unnamed-rule';
|
|
44
|
+
const adapter = (nodes, concepts) => {
|
|
45
|
+
const index = buildRuleIndex(nodes, concepts);
|
|
46
|
+
// Pass empty filePath — the review pipeline patches it downstream
|
|
47
|
+
// (same pattern as ground-layer rules in ground-layer.ts:45)
|
|
48
|
+
return evaluateRule(ruleNode, index, '');
|
|
49
|
+
};
|
|
50
|
+
adapter.ruleId = ruleId;
|
|
51
|
+
return adapter;
|
|
52
|
+
}
|
|
53
|
+
// ── Loader ──────────────────────────────────────────────────────────────
|
|
54
|
+
/**
|
|
55
|
+
* Load rules from a single .kern file, resolving imports recursively.
|
|
56
|
+
* The visited set guards against circular imports.
|
|
57
|
+
* allowedRoots constrains import resolution — imports that escape these dirs are rejected.
|
|
58
|
+
*/
|
|
59
|
+
function loadRulesFromFile(filePath, rules, visited, skipIds = new Set(), allowedRoots = []) {
|
|
60
|
+
const absPath = resolve(filePath);
|
|
61
|
+
if (visited.has(absPath))
|
|
62
|
+
return;
|
|
63
|
+
visited.add(absPath);
|
|
64
|
+
if (!existsSync(absPath)) {
|
|
65
|
+
console.warn(`[kern-native] Import not found: ${absPath}`);
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
try {
|
|
69
|
+
const source = readFileSync(absPath, 'utf-8');
|
|
70
|
+
const doc = parseDocument(source);
|
|
71
|
+
const children = doc.children || [];
|
|
72
|
+
// Resolve imports first (relative to importing file)
|
|
73
|
+
for (const node of children) {
|
|
74
|
+
if (node.type !== 'import')
|
|
75
|
+
continue;
|
|
76
|
+
const from = node.props?.from || '';
|
|
77
|
+
if (!from || !from.endsWith('.kern'))
|
|
78
|
+
continue;
|
|
79
|
+
const importPath = resolve(dirname(absPath), from);
|
|
80
|
+
// Containment check: resolved import must be inside an allowed root
|
|
81
|
+
if (allowedRoots.length > 0) {
|
|
82
|
+
let realImportPath;
|
|
83
|
+
try {
|
|
84
|
+
realImportPath = realpathSync(importPath);
|
|
85
|
+
}
|
|
86
|
+
catch {
|
|
87
|
+
realImportPath = importPath;
|
|
88
|
+
}
|
|
89
|
+
const confined = allowedRoots.some(root => realImportPath.startsWith(root + '/') || realImportPath === root);
|
|
90
|
+
if (!confined) {
|
|
91
|
+
console.warn(`[kern-native] Import '${from}' escapes allowed roots — skipped`);
|
|
92
|
+
continue;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
loadRulesFromFile(importPath, rules, visited, skipIds, allowedRoots);
|
|
96
|
+
}
|
|
97
|
+
// Extract and validate rule nodes
|
|
98
|
+
for (const ruleNode of children.filter(n => n.type === 'rule')) {
|
|
99
|
+
const errors = validateRule(ruleNode);
|
|
100
|
+
if (errors.length > 0) {
|
|
101
|
+
console.warn(`[kern-native] Skipping invalid rule in ${absPath}: ${errors.join(', ')}`);
|
|
102
|
+
continue;
|
|
103
|
+
}
|
|
104
|
+
const ruleId = ruleNode.props?.id;
|
|
105
|
+
if (ruleId && skipIds.has(ruleId)) {
|
|
106
|
+
console.warn(`[kern-native] Skipping duplicate ruleId '${ruleId}' from ${absPath} (already loaded)`);
|
|
107
|
+
continue;
|
|
108
|
+
}
|
|
109
|
+
const adapter = nativeRuleAdapter(ruleNode);
|
|
110
|
+
rules.push(adapter);
|
|
111
|
+
if (ruleId)
|
|
112
|
+
skipIds.add(ruleId);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
catch (err) {
|
|
116
|
+
console.warn(`[kern-native] Failed to parse ${absPath}: ${err.message}`);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Load native .kern rule files from a directory.
|
|
121
|
+
* Returns KernLintRule adapters for all valid rules found.
|
|
122
|
+
* Supports `import from="other.kern"` for rule composition.
|
|
123
|
+
*/
|
|
124
|
+
export function loadNativeRules(dirs, skipIds = new Set()) {
|
|
125
|
+
const rules = [];
|
|
126
|
+
const visited = new Set();
|
|
127
|
+
// Compute real paths of allowed roots for containment checks
|
|
128
|
+
const allowedRoots = dirs.map(d => { try {
|
|
129
|
+
return realpathSync(resolve(d));
|
|
130
|
+
}
|
|
131
|
+
catch {
|
|
132
|
+
return resolve(d);
|
|
133
|
+
} });
|
|
134
|
+
for (const dir of dirs) {
|
|
135
|
+
if (!existsSync(dir))
|
|
136
|
+
continue;
|
|
137
|
+
const files = readdirSync(dir).filter((f) => f.endsWith('.kern'));
|
|
138
|
+
for (const file of files) {
|
|
139
|
+
loadRulesFromFile(join(dir, file), rules, visited, skipIds, allowedRoots);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
return rules;
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Load native rules from the built-in rules directory.
|
|
146
|
+
*/
|
|
147
|
+
export function loadBuiltinNativeRules() {
|
|
148
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
149
|
+
// Try dist/rules/native first, fall back to src/rules/native (dev mode)
|
|
150
|
+
const distDir = resolve(__dirname, 'rules', 'native');
|
|
151
|
+
const srcDir = resolve(__dirname, '..', 'src', 'rules', 'native');
|
|
152
|
+
const builtinDir = existsSync(distDir) ? distDir : srcDir;
|
|
153
|
+
return loadNativeRules([builtinDir]);
|
|
154
|
+
}
|
|
155
|
+
//# sourceMappingURL=rule-loader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rule-loader.js","sourceRoot":"","sources":["../src/rule-loader.ts"],"names":[],"mappings":"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"}
|