@kernlang/review 3.1.9 → 3.3.4

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 (94) hide show
  1. package/dist/cache.js +143 -2
  2. package/dist/cache.js.map +1 -1
  3. package/dist/call-graph.d.ts +4 -1
  4. package/dist/call-graph.js +290 -25
  5. package/dist/call-graph.js.map +1 -1
  6. package/dist/external-tools.d.ts +23 -4
  7. package/dist/external-tools.js +68 -12
  8. package/dist/external-tools.js.map +1 -1
  9. package/dist/file-context.d.ts +6 -0
  10. package/dist/file-context.js +6 -1
  11. package/dist/file-context.js.map +1 -1
  12. package/dist/graph.js +149 -39
  13. package/dist/graph.js.map +1 -1
  14. package/dist/index.d.ts +27 -3
  15. package/dist/index.js +254 -41
  16. package/dist/index.js.map +1 -1
  17. package/dist/inferrer.d.ts +5 -0
  18. package/dist/inferrer.js +1 -1
  19. package/dist/inferrer.js.map +1 -1
  20. package/dist/mappers/ts-concepts.js +31 -6
  21. package/dist/mappers/ts-concepts.js.map +1 -1
  22. package/dist/public-api.d.ts +73 -0
  23. package/dist/public-api.js +351 -0
  24. package/dist/public-api.js.map +1 -0
  25. package/dist/reporter.d.ts +5 -0
  26. package/dist/reporter.js +119 -84
  27. package/dist/reporter.js.map +1 -1
  28. package/dist/review-health.d.ts +38 -0
  29. package/dist/review-health.js +60 -0
  30. package/dist/review-health.js.map +1 -0
  31. package/dist/rules/a11y.d.ts +10 -0
  32. package/dist/rules/a11y.js +294 -0
  33. package/dist/rules/a11y.js.map +1 -0
  34. package/dist/rules/async.d.ts +8 -0
  35. package/dist/rules/async.js +142 -0
  36. package/dist/rules/async.js.map +1 -0
  37. package/dist/rules/base.js +112 -87
  38. package/dist/rules/base.js.map +1 -1
  39. package/dist/rules/confidence.d.ts +2 -2
  40. package/dist/rules/confidence.js +32 -15
  41. package/dist/rules/confidence.js.map +1 -1
  42. package/dist/rules/dead-code.d.ts +2 -1
  43. package/dist/rules/dead-code.js +49 -3
  44. package/dist/rules/dead-code.js.map +1 -1
  45. package/dist/rules/index.d.ts +12 -0
  46. package/dist/rules/index.js +414 -4
  47. package/dist/rules/index.js.map +1 -1
  48. package/dist/rules/ink.js +41 -0
  49. package/dist/rules/ink.js.map +1 -1
  50. package/dist/rules/kern-source-cross-file.d.ts +2 -0
  51. package/dist/rules/kern-source-cross-file.js +102 -0
  52. package/dist/rules/kern-source-cross-file.js.map +1 -0
  53. package/dist/rules/kern-source.js +145 -18
  54. package/dist/rules/kern-source.js.map +1 -1
  55. package/dist/rules/nextjs-app-router.d.ts +11 -0
  56. package/dist/rules/nextjs-app-router.js +1182 -0
  57. package/dist/rules/nextjs-app-router.js.map +1 -0
  58. package/dist/rules/nextjs.js +266 -7
  59. package/dist/rules/nextjs.js.map +1 -1
  60. package/dist/rules/perf.d.ts +11 -0
  61. package/dist/rules/perf.js +131 -0
  62. package/dist/rules/perf.js.map +1 -0
  63. package/dist/rules/react-composition.d.ts +12 -0
  64. package/dist/rules/react-composition.js +741 -0
  65. package/dist/rules/react-composition.js.map +1 -0
  66. package/dist/rules/react-hooks.d.ts +11 -0
  67. package/dist/rules/react-hooks.js +429 -0
  68. package/dist/rules/react-hooks.js.map +1 -0
  69. package/dist/rules/react.js +265 -49
  70. package/dist/rules/react.js.map +1 -1
  71. package/dist/rules/security-v5.d.ts +11 -0
  72. package/dist/rules/security-v5.js +200 -0
  73. package/dist/rules/security-v5.js.map +1 -0
  74. package/dist/rules/utils.d.ts +52 -1
  75. package/dist/rules/utils.js +159 -0
  76. package/dist/rules/utils.js.map +1 -1
  77. package/dist/semantic-diff.js +1 -1
  78. package/dist/semantic-diff.js.map +1 -1
  79. package/dist/taint-ast.js +260 -10
  80. package/dist/taint-ast.js.map +1 -1
  81. package/dist/taint-crossfile.d.ts +30 -2
  82. package/dist/taint-crossfile.js +280 -59
  83. package/dist/taint-crossfile.js.map +1 -1
  84. package/dist/taint-findings.js +3 -0
  85. package/dist/taint-findings.js.map +1 -1
  86. package/dist/taint-types.d.ts +4 -3
  87. package/dist/taint-types.js +70 -6
  88. package/dist/taint-types.js.map +1 -1
  89. package/dist/taint.d.ts +1 -1
  90. package/dist/taint.js +1 -1
  91. package/dist/taint.js.map +1 -1
  92. package/dist/types.d.ts +98 -0
  93. package/dist/types.js.map +1 -1
  94. package/package.json +3 -3
@@ -13,14 +13,14 @@ function props(node) {
13
13
  function loc(node) {
14
14
  return { line: node.loc?.line || 0, col: node.loc?.col || 1 };
15
15
  }
16
- function finding(ruleId, severity, category, message, line, col, extra) {
16
+ function finding(ruleId, severity, category, message, line, col, file = '', extra) {
17
17
  return {
18
18
  source: 'kern',
19
19
  ruleId,
20
20
  severity,
21
21
  category,
22
22
  message,
23
- primarySpan: { file: '', startLine: line, startCol: col, endLine: line, endCol: col },
23
+ primarySpan: { file, startLine: line, startCol: col, endLine: line, endCol: col },
24
24
  fingerprint: createFingerprint(ruleId, line, col),
25
25
  ...extra,
26
26
  };
@@ -34,7 +34,7 @@ function confidenceMissingSource(graph) {
34
34
  continue;
35
35
  for (const src of cnode.spec.sources || []) {
36
36
  if (!graph.nodes.has(src)) {
37
- findings.push(finding('confidence-missing-source', 'error', 'pattern', `Confidence source '${src}' not found (referenced by '${cnode.name}')`, cnode.nodeRef.line, 1));
37
+ findings.push(finding('confidence-missing-source', 'error', 'pattern', `Confidence source '${src}' not found (referenced by '${cnode.name}')`, cnode.nodeRef.line, 1, cnode.sourceFile));
38
38
  }
39
39
  }
40
40
  }
@@ -45,7 +45,7 @@ function confidenceCycle(graph) {
45
45
  const findings = [];
46
46
  for (const cycle of graph.cycles) {
47
47
  const first = graph.nodes.get(cycle[0]);
48
- findings.push(finding('confidence-cycle', 'error', 'pattern', `Circular confidence dependency: ${cycle.join(' → ')}`, first?.nodeRef.line ?? 0, 1));
48
+ findings.push(finding('confidence-cycle', 'error', 'pattern', `Circular confidence dependency: ${cycle.join(' → ')}`, first?.nodeRef.line ?? 0, 1, first?.sourceFile ?? ''));
49
49
  }
50
50
  return findings;
51
51
  }
@@ -56,7 +56,7 @@ function confidenceNeedsUnresolved(graph) {
56
56
  const unresolvedNeeds = cnode.needs.filter((n) => !n.resolved);
57
57
  if (unresolvedNeeds.length > 0) {
58
58
  const descs = unresolvedNeeds.map((n) => n.what).join(', ');
59
- findings.push(finding('confidence-needs-unresolved', 'info', 'pattern', `'${cnode.name}' has ${unresolvedNeeds.length} unresolved need(s): ${descs}`, cnode.nodeRef.line, 1));
59
+ findings.push(finding('confidence-needs-unresolved', 'info', 'pattern', `'${cnode.name}' has ${unresolvedNeeds.length} unresolved need(s): ${descs}`, cnode.nodeRef.line, 1, cnode.sourceFile));
60
60
  }
61
61
  }
62
62
  return findings;
@@ -67,7 +67,7 @@ function confidenceLow(graph, threshold = 0.5) {
67
67
  for (const cnode of graph.nodes.values()) {
68
68
  // Guard: only fire when resolved > 0 && resolved < threshold
69
69
  if (cnode.resolved !== null && cnode.resolved > 0 && cnode.resolved < threshold) {
70
- findings.push(finding('confidence-low', 'warning', 'pattern', `'${cnode.name}' has low confidence: ${cnode.resolved}`, cnode.nodeRef.line, 1));
70
+ findings.push(finding('confidence-low', 'warning', 'pattern', `'${cnode.name}' has low confidence: ${cnode.resolved}`, cnode.nodeRef.line, 1, cnode.sourceFile));
71
71
  }
72
72
  }
73
73
  return findings;
@@ -80,14 +80,14 @@ function confidenceImpossible(graph) {
80
80
  continue;
81
81
  for (const need of cnode.needs) {
82
82
  if (need.wouldRaiseTo !== undefined && need.wouldRaiseTo < cnode.spec.value) {
83
- findings.push(finding('confidence-impossible', 'error', 'pattern', `'${cnode.name}' need "${need.what}" has would-raise-to=${need.wouldRaiseTo} which is less than current confidence ${cnode.spec.value}`, cnode.nodeRef.line, 1));
83
+ findings.push(finding('confidence-impossible', 'error', 'pattern', `'${cnode.name}' need "${need.what}" has would-raise-to=${need.wouldRaiseTo} which is less than current confidence ${cnode.spec.value}`, cnode.nodeRef.line, 1, cnode.sourceFile));
84
84
  }
85
85
  }
86
86
  }
87
87
  return findings;
88
88
  }
89
89
  /** Anonymous node (no name) has confidence=from:X — can't be referenced by others */
90
- function confidenceAnonymousRef(irNodes) {
90
+ function confidenceAnonymousRef(irNodes, locateFile) {
91
91
  const findings = [];
92
92
  for (const node of irNodes) {
93
93
  const conf = props(node).confidence;
@@ -99,7 +99,7 @@ function confidenceAnonymousRef(irNodes) {
99
99
  const spec = parseConfidence(conf);
100
100
  if (spec && spec.kind === 'inherited') {
101
101
  const { line, col } = loc(node);
102
- findings.push(finding('confidence-anonymous-ref', 'warning', 'pattern', `Anonymous ${node.type} node has inherited confidence but can't be referenced by others`, line, col));
102
+ findings.push(finding('confidence-anonymous-ref', 'warning', 'pattern', `Anonymous ${node.type} node has inherited confidence but can't be referenced by others`, line, col, locateFile?.(node, line, col) ?? ''));
103
103
  }
104
104
  }
105
105
  return findings;
@@ -108,43 +108,60 @@ function confidenceAnonymousRef(irNodes) {
108
108
  function confidenceDuplicateName(graph) {
109
109
  const findings = [];
110
110
  for (const dup of graph.duplicates) {
111
- findings.push(finding('confidence-duplicate-name', 'error', 'pattern', `Confidence node '${dup.name}' defined in multiple files: ${dup.files.join(', ')}`, 0, 1));
111
+ for (const file of dup.files) {
112
+ const relatedSpans = dup.files
113
+ .filter((other) => other !== file)
114
+ .map((other) => ({
115
+ file: other,
116
+ startLine: 1,
117
+ startCol: 1,
118
+ endLine: 1,
119
+ endCol: 1,
120
+ }));
121
+ findings.push(finding('confidence-duplicate-name', 'error', 'pattern', `Confidence node '${dup.name}' defined in multiple files: ${dup.files.join(', ')}`, 1, 1, file, { relatedSpans }));
122
+ }
112
123
  }
113
124
  return findings;
114
125
  }
115
126
  // ── Exported lint entry points ───────────────────────────────────────────
116
127
  /** Run all confidence lint rules against a flat list of IR nodes (single file). */
117
- export function lintConfidenceGraph(irNodes) {
128
+ export function lintConfidenceGraph(irNodes, filePath) {
118
129
  const hasConfidence = irNodes.some((n) => props(n).confidence !== undefined);
119
130
  if (!hasConfidence)
120
131
  return [];
121
132
  const graph = buildConfidenceGraph(irNodes);
122
- return runGraphRules(graph, irNodes);
133
+ return runGraphRules(graph, irNodes, filePath ? () => filePath : undefined);
123
134
  }
124
135
  /** Run all confidence lint rules against multiple files (cross-file resolution). */
125
136
  export function lintMultiFileConfidenceGraph(fileMap) {
126
137
  // Collect all nodes to check for confidence props
127
138
  const allNodes = [];
139
+ const nodeFiles = new Map();
128
140
  for (const nodes of fileMap.values()) {
129
141
  allNodes.push(...nodes);
130
142
  }
143
+ for (const [filePath, nodes] of fileMap) {
144
+ for (const node of nodes) {
145
+ nodeFiles.set(node, filePath);
146
+ }
147
+ }
131
148
  const hasConfidence = allNodes.some((n) => props(n).confidence !== undefined);
132
149
  if (!hasConfidence)
133
150
  return [];
134
151
  const graph = buildMultiFileConfidenceGraph(fileMap);
135
- const findings = runGraphRules(graph, allNodes);
152
+ const findings = runGraphRules(graph, allNodes, (node) => nodeFiles.get(node));
136
153
  findings.push(...confidenceDuplicateName(graph));
137
154
  return findings;
138
155
  }
139
156
  /** Shared rule runner for both single-file and multi-file graphs. */
140
- function runGraphRules(graph, allNodes) {
157
+ function runGraphRules(graph, allNodes, locateFile) {
141
158
  const findings = [];
142
159
  findings.push(...confidenceMissingSource(graph));
143
160
  findings.push(...confidenceCycle(graph));
144
161
  findings.push(...confidenceNeedsUnresolved(graph));
145
162
  findings.push(...confidenceLow(graph));
146
163
  findings.push(...confidenceImpossible(graph));
147
- findings.push(...confidenceAnonymousRef(allNodes));
164
+ findings.push(...confidenceAnonymousRef(allNodes, locateFile));
148
165
  return findings;
149
166
  }
150
167
  export const CONFIDENCE_RULES = {
@@ -1 +1 @@
1
- {"version":3,"file":"confidence.js","sourceRoot":"","sources":["../../src/rules/confidence.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,EAAE,oBAAoB,EAAE,6BAA6B,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAExG,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAEhD,4EAA4E;AAE5E,SAAS,KAAK,CAAC,IAAY;IACzB,OAAO,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC;AAC1B,CAAC;AAED,SAAS,GAAG,CAAC,IAAY;IACvB,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,GAAG,EAAE,IAAI,IAAI,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC;AAChE,CAAC;AAED,SAAS,OAAO,CACd,MAAc,EACd,QAAsC,EACtC,QAAmC,EACnC,OAAe,EACf,IAAY,EACZ,GAAW,EACX,KAA8B;IAE9B,OAAO;QACL,MAAM,EAAE,MAAM;QACd,MAAM;QACN,QAAQ;QACR,QAAQ;QACR,OAAO;QACP,WAAW,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE;QACrF,WAAW,EAAE,iBAAiB,CAAC,MAAM,EAAE,IAAI,EAAE,GAAG,CAAC;QACjD,GAAG,KAAK;KACT,CAAC;AACJ,CAAC;AAED,4EAA4E;AAE5E,iDAAiD;AACjD,SAAS,uBAAuB,CAAC,KAAsB;IACrD,MAAM,QAAQ,GAAoB,EAAE,CAAC;IACrC,KAAK,MAAM,KAAK,IAAI,KAAK,CAAC,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC;QACzC,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,KAAK,WAAW;YAAE,SAAS;QAC9C,KAAK,MAAM,GAAG,IAAI,KAAK,CAAC,IAAI,CAAC,OAAO,IAAI,EAAE,EAAE,CAAC;YAC3C,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;gBAC1B,QAAQ,CAAC,IAAI,CACX,OAAO,CACL,2BAA2B,EAC3B,OAAO,EACP,SAAS,EACT,sBAAsB,GAAG,+BAA+B,KAAK,CAAC,IAAI,IAAI,EACtE,KAAK,CAAC,OAAO,CAAC,IAAI,EAClB,CAAC,CACF,CACF,CAAC;YACJ,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,qCAAqC;AACrC,SAAS,eAAe,CAAC,KAAsB;IAC7C,MAAM,QAAQ,GAAoB,EAAE,CAAC;IACrC,KAAK,MAAM,KAAK,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;QACjC,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QACxC,QAAQ,CAAC,IAAI,CACX,OAAO,CACL,kBAAkB,EAClB,OAAO,EACP,SAAS,EACT,mCAAmC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,EACtD,KAAK,EAAE,OAAO,CAAC,IAAI,IAAI,CAAC,EACxB,CAAC,CACF,CACF,CAAC;IACJ,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,yCAAyC;AACzC,SAAS,yBAAyB,CAAC,KAAsB;IACvD,MAAM,QAAQ,GAAoB,EAAE,CAAC;IACrC,KAAK,MAAM,KAAK,IAAI,KAAK,CAAC,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC;QACzC,MAAM,eAAe,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;QAC/D,IAAI,eAAe,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC/B,MAAM,KAAK,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC5D,QAAQ,CAAC,IAAI,CACX,OAAO,CACL,6BAA6B,EAC7B,MAAM,EACN,SAAS,EACT,IAAI,KAAK,CAAC,IAAI,SAAS,eAAe,CAAC,MAAM,wBAAwB,KAAK,EAAE,EAC5E,KAAK,CAAC,OAAO,CAAC,IAAI,EAClB,CAAC,CACF,CACF,CAAC;QACJ,CAAC;IACH,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,gDAAgD;AAChD,SAAS,aAAa,CAAC,KAAsB,EAAE,SAAS,GAAG,GAAG;IAC5D,MAAM,QAAQ,GAAoB,EAAE,CAAC;IACrC,KAAK,MAAM,KAAK,IAAI,KAAK,CAAC,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC;QACzC,6DAA6D;QAC7D,IAAI,KAAK,CAAC,QAAQ,KAAK,IAAI,IAAI,KAAK,CAAC,QAAQ,GAAG,CAAC,IAAI,KAAK,CAAC,QAAQ,GAAG,SAAS,EAAE,CAAC;YAChF,QAAQ,CAAC,IAAI,CACX,OAAO,CACL,gBAAgB,EAChB,SAAS,EACT,SAAS,EACT,IAAI,KAAK,CAAC,IAAI,yBAAyB,KAAK,CAAC,QAAQ,EAAE,EACvD,KAAK,CAAC,OAAO,CAAC,IAAI,EAClB,CAAC,CACF,CACF,CAAC;QACJ,CAAC;IACH,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,kDAAkD;AAClD,SAAS,oBAAoB,CAAC,KAAsB;IAClD,MAAM,QAAQ,GAAoB,EAAE,CAAC;IACrC,KAAK,MAAM,KAAK,IAAI,KAAK,CAAC,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC;QACzC,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,KAAK,SAAS,IAAI,KAAK,CAAC,IAAI,CAAC,KAAK,KAAK,SAAS;YAAE,SAAS;QAC9E,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;YAC/B,IAAI,IAAI,CAAC,YAAY,KAAK,SAAS,IAAI,IAAI,CAAC,YAAY,GAAG,KAAK,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;gBAC5E,QAAQ,CAAC,IAAI,CACX,OAAO,CACL,uBAAuB,EACvB,OAAO,EACP,SAAS,EACT,IAAI,KAAK,CAAC,IAAI,WAAW,IAAI,CAAC,IAAI,wBAAwB,IAAI,CAAC,YAAY,0CAA0C,KAAK,CAAC,IAAI,CAAC,KAAK,EAAE,EACvI,KAAK,CAAC,OAAO,CAAC,IAAI,EAClB,CAAC,CACF,CACF,CAAC;YACJ,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,qFAAqF;AACrF,SAAS,sBAAsB,CAAC,OAAiB;IAC/C,MAAM,QAAQ,GAAoB,EAAE,CAAC;IACrC,KAAK,MAAM,IAAI,IAAI,OAAO,EAAE,CAAC;QAC3B,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,UAAU,CAAC;QACpC,IAAI,IAAI,KAAK,SAAS;YAAE,SAAS;QACjC,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,IAA0B,CAAC;QACpD,IAAI,IAAI;YAAE,SAAS,CAAC,oBAAoB;QACxC,MAAM,IAAI,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC;QACnC,IAAI,IAAI,IAAI,IAAI,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;YACtC,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,GAAG,CAAC,IAAI,CAAC,CAAC;YAChC,QAAQ,CAAC,IAAI,CACX,OAAO,CACL,0BAA0B,EAC1B,SAAS,EACT,SAAS,EACT,aAAa,IAAI,CAAC,IAAI,kEAAkE,EACxF,IAAI,EACJ,GAAG,CACJ,CACF,CAAC;QACJ,CAAC;IACH,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,kCAAkC;AAClC,SAAS,uBAAuB,CAAC,KAA+B;IAC9D,MAAM,QAAQ,GAAoB,EAAE,CAAC;IACrC,KAAK,MAAM,GAAG,IAAI,KAAK,CAAC,UAAU,EAAE,CAAC;QACnC,QAAQ,CAAC,IAAI,CACX,OAAO,CACL,2BAA2B,EAC3B,OAAO,EACP,SAAS,EACT,oBAAoB,GAAG,CAAC,IAAI,gCAAgC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EAClF,CAAC,EACD,CAAC,CACF,CACF,CAAC;IACJ,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,4EAA4E;AAE5E,mFAAmF;AACnF,MAAM,UAAU,mBAAmB,CAAC,OAAiB;IACnD,MAAM,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,UAAU,KAAK,SAAS,CAAC,CAAC;IAC7E,IAAI,CAAC,aAAa;QAAE,OAAO,EAAE,CAAC;IAE9B,MAAM,KAAK,GAAG,oBAAoB,CAAC,OAAO,CAAC,CAAC;IAC5C,OAAO,aAAa,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;AACvC,CAAC;AAED,oFAAoF;AACpF,MAAM,UAAU,4BAA4B,CAAC,OAA8B;IACzE,kDAAkD;IAClD,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,KAAK,MAAM,KAAK,IAAI,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;QACrC,QAAQ,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,CAAC;IAC1B,CAAC;IACD,MAAM,aAAa,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,UAAU,KAAK,SAAS,CAAC,CAAC;IAC9E,IAAI,CAAC,aAAa;QAAE,OAAO,EAAE,CAAC;IAE9B,MAAM,KAAK,GAAG,6BAA6B,CAAC,OAAO,CAAC,CAAC;IACrD,MAAM,QAAQ,GAAG,aAAa,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;IAChD,QAAQ,CAAC,IAAI,CAAC,GAAG,uBAAuB,CAAC,KAAK,CAAC,CAAC,CAAC;IACjD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,qEAAqE;AACrE,SAAS,aAAa,CAAC,KAAsB,EAAE,QAAkB;IAC/D,MAAM,QAAQ,GAAoB,EAAE,CAAC;IACrC,QAAQ,CAAC,IAAI,CAAC,GAAG,uBAAuB,CAAC,KAAK,CAAC,CAAC,CAAC;IACjD,QAAQ,CAAC,IAAI,CAAC,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC,CAAC;IACzC,QAAQ,CAAC,IAAI,CAAC,GAAG,yBAAyB,CAAC,KAAK,CAAC,CAAC,CAAC;IACnD,QAAQ,CAAC,IAAI,CAAC,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC;IACvC,QAAQ,CAAC,IAAI,CAAC,GAAG,oBAAoB,CAAC,KAAK,CAAC,CAAC,CAAC;IAC9C,QAAQ,CAAC,IAAI,CAAC,GAAG,sBAAsB,CAAC,QAAQ,CAAC,CAAC,CAAC;IACnD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,MAAM,CAAC,MAAM,gBAAgB,GAAG;IAC9B,uBAAuB;IACvB,eAAe;IACf,yBAAyB;IACzB,aAAa;IACb,oBAAoB;IACpB,sBAAsB;IACtB,uBAAuB;CACxB,CAAC"}
1
+ {"version":3,"file":"confidence.js","sourceRoot":"","sources":["../../src/rules/confidence.ts"],"names":[],"mappings":"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"}
@@ -5,6 +5,7 @@
5
5
  * Confidence is adjusted based on call graph resolution quality.
6
6
  */
7
7
  import type { CallGraph } from '../call-graph.js';
8
+ import { type PublicApiMap } from '../public-api.js';
8
9
  import type { ReviewFinding } from '../types.js';
9
- export declare function deadExportRule(callGraph: CallGraph, filePath: string): ReviewFinding[];
10
+ export declare function deadExportRule(callGraph: CallGraph, filePath: string, publicApi?: PublicApiMap): ReviewFinding[];
10
11
  export declare function crossFileAsyncRule(callGraph: CallGraph, filePath: string): ReviewFinding[];
@@ -4,23 +4,38 @@
4
4
  * Requires call graph context (only available in --graph mode or --recursive with graph).
5
5
  * Confidence is adjusted based on call graph resolution quality.
6
6
  */
7
+ import { isPublicApi } from '../public-api.js';
7
8
  import { createFingerprint } from '../types.js';
8
9
  function span(file, line, col = 1) {
9
10
  return { file, startLine: line, startCol: col, endLine: line, endCol: col };
10
11
  }
11
12
  // ── Rule: dead-export ───────────────────────────────────────────────────
12
13
  // Exported function/variable that is never imported by any file in the graph.
13
- export function deadExportRule(callGraph, filePath) {
14
+ export function deadExportRule(callGraph, filePath, publicApi) {
14
15
  const findings = [];
15
16
  for (const key of callGraph.deadExports) {
16
17
  const fn = callGraph.functions.get(key);
17
18
  if (!fn || fn.filePath !== filePath)
18
19
  continue;
19
- // Skip entry point files — their exports are consumed externally
20
- // (we can't know if something is used outside the analyzed graph)
21
20
  // Skip test files
22
21
  if (fn.filePath.includes('.test.') || fn.filePath.includes('.spec.'))
23
22
  continue;
23
+ // Skip intentional public API — package.json entries, curated barrels, config overrides.
24
+ // External consumers (other packages, dynamic loaders, platform entry points) won't
25
+ // appear in the analyzed graph, so their imports can't be observed.
26
+ if (publicApi && isPublicApi(publicApi, fn.filePath, fn.name))
27
+ continue;
28
+ // Class methods inherit public-API status from their enclosing class. The
29
+ // call graph tracks `Class.method` as a separate exported symbol whose
30
+ // only cross-file callers are opaque `obj.method()` property accesses
31
+ // (unresolvable by static analysis). If the class itself is public,
32
+ // every method is reachable via the class — flagging them individually
33
+ // produces a wave of FPs on any package that ships a class.
34
+ if (publicApi && fn.name.includes('.')) {
35
+ const className = fn.name.split('.')[0];
36
+ if (isPublicApi(publicApi, fn.filePath, className))
37
+ continue;
38
+ }
24
39
  // Confidence depends on how many calls in the graph were unresolved
25
40
  // If lots of calls are unresolved, the dead export might actually be used via a dynamic path
26
41
  const totalCalls = [...callGraph.functions.values()].reduce((sum, f) => sum + f.calls.length, 0);
@@ -36,6 +51,19 @@ export function deadExportRule(callGraph, filePath) {
36
51
  fingerprint: createFingerprint('dead-export', fn.line, 1),
37
52
  confidence,
38
53
  suggestion: `Remove the export, or if used externally (by consumers of this package), add to the public API documentation.`,
54
+ provenance: {
55
+ summary: fn.calledBy.length === 0
56
+ ? `No resolved callers found in the analyzed graph for '${fn.name}'.`
57
+ : `Only unresolved callers were found for '${fn.name}'.`,
58
+ steps: [
59
+ {
60
+ kind: 'source',
61
+ location: span(filePath, fn.line),
62
+ label: `export ${fn.name}`,
63
+ detail: `Exported symbol '${fn.name}' has no resolved incoming call edges in the analyzed graph.`,
64
+ },
65
+ ],
66
+ },
39
67
  });
40
68
  }
41
69
  return findings;
@@ -64,9 +92,27 @@ export function crossFileAsyncRule(callGraph, filePath) {
64
92
  category: 'bug',
65
93
  message: `Cross-file: '${call.targetName}()' from ${target.filePath.split('/').pop()} is async but called without await`,
66
94
  primarySpan: span(filePath, call.line),
95
+ relatedSpans: [span(target.filePath, target.line)],
67
96
  fingerprint: createFingerprint('floating-promise', call.line, 2),
68
97
  confidence: 0.9,
69
98
  suggestion: `Add 'await' before the call, or use 'void' if intentionally fire-and-forget.`,
99
+ provenance: {
100
+ summary: `${fn.name}() calls async ${target.name}() across a file boundary without await.`,
101
+ steps: [
102
+ {
103
+ kind: 'call',
104
+ location: span(filePath, call.line),
105
+ label: `${fn.name}() → ${call.targetName}()`,
106
+ detail: `Cross-file call in ${filePath.split('/').pop()} is not awaited.`,
107
+ },
108
+ {
109
+ kind: 'call',
110
+ location: span(target.filePath, target.line),
111
+ label: `async ${target.name}()`,
112
+ detail: `Target function is declared async in ${target.filePath.split('/').pop()}.`,
113
+ },
114
+ ],
115
+ },
70
116
  });
71
117
  }
72
118
  }
@@ -1 +1 @@
1
- {"version":3,"file":"dead-code.js","sourceRoot":"","sources":["../../src/rules/dead-code.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"dead-code.js","sourceRoot":"","sources":["../../src/rules/dead-code.ts"],"names":[],"mappings":"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"}
@@ -24,6 +24,18 @@ export interface RuleInfo {
24
24
  layer: string;
25
25
  severity: 'error' | 'warning' | 'info';
26
26
  description: string;
27
+ /**
28
+ * Precision hint used by kern-sight to stratify rules in the sidebar.
29
+ * 'high' — rule has strong substrate (taint graph, file-context, ground-truth AST); ship on.
30
+ * 'medium' — rule relies on heuristics; consider hide-by-default after first scan.
31
+ * 'experimental' — rule may be noisy; hide-by-default, promote after signal data proves it out.
32
+ */
33
+ precision?: 'high' | 'medium' | 'experimental';
34
+ /**
35
+ * Wave number in the rollout plan. Used by kern-sight to group new rules
36
+ * visually and by `--list-rules` to surface what just landed. Wave 0 = substrate.
37
+ */
38
+ rolloutPhase?: number;
27
39
  }
28
40
  /**
29
41
  * Get the rule registry, optionally filtered by target.