code-auditor-mcp 3.5.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.
- package/.claude-plugin/marketplace.json +1 -1
- package/CHANGELOG.md +62 -0
- package/dist/analyzers/applicability.d.ts +6 -5
- package/dist/analyzers/applicability.d.ts.map +1 -1
- package/dist/analyzers/applicability.js +1 -26
- package/dist/analyzers/applicability.js.map +1 -1
- package/dist/analyzers/cross-language/DependencyGraphBuilder.d.ts.map +1 -1
- package/dist/analyzers/cross-language/DependencyGraphBuilder.js +12 -1
- package/dist/analyzers/cross-language/DependencyGraphBuilder.js.map +1 -1
- package/dist/analyzers/ruleRegistry.d.ts +14 -12
- package/dist/analyzers/ruleRegistry.d.ts.map +1 -1
- package/dist/analyzers/ruleRegistry.js +138 -98
- package/dist/analyzers/ruleRegistry.js.map +1 -1
- package/dist/analyzers/ruleTiming.d.ts +2 -2
- package/dist/analyzers/ruleTiming.js +2 -2
- package/dist/analyzers/universal/UniversalDRYAnalyzer.d.ts +29 -0
- package/dist/analyzers/universal/UniversalDRYAnalyzer.d.ts.map +1 -1
- package/dist/analyzers/universal/UniversalDRYAnalyzer.js +376 -6
- package/dist/analyzers/universal/UniversalDRYAnalyzer.js.map +1 -1
- package/dist/analyzers/universal/UniversalDataAccessAnalyzer.d.ts +6 -0
- package/dist/analyzers/universal/UniversalDataAccessAnalyzer.d.ts.map +1 -1
- package/dist/analyzers/universal/UniversalDataAccessAnalyzer.js +41 -7
- package/dist/analyzers/universal/UniversalDataAccessAnalyzer.js.map +1 -1
- package/dist/analyzers/universal/UniversalDocumentationAnalyzer.d.ts.map +1 -1
- package/dist/analyzers/universal/UniversalDocumentationAnalyzer.js +13 -2
- package/dist/analyzers/universal/UniversalDocumentationAnalyzer.js.map +1 -1
- package/dist/analyzers/universal/UniversalSOLIDAnalyzer.d.ts +20 -5
- package/dist/analyzers/universal/UniversalSOLIDAnalyzer.d.ts.map +1 -1
- package/dist/analyzers/universal/UniversalSOLIDAnalyzer.js +83 -14
- package/dist/analyzers/universal/UniversalSOLIDAnalyzer.js.map +1 -1
- package/dist/analyzers/universal/UniversalSchemaAnalyzer.d.ts.map +1 -1
- package/dist/analyzers/universal/UniversalSchemaAnalyzer.js +5 -2
- package/dist/analyzers/universal/UniversalSchemaAnalyzer.js.map +1 -1
- package/dist/analyzers/universal/UniversalSecretsAnalyzer.d.ts +55 -0
- package/dist/analyzers/universal/UniversalSecretsAnalyzer.d.ts.map +1 -0
- package/dist/analyzers/universal/UniversalSecretsAnalyzer.js +318 -0
- package/dist/analyzers/universal/UniversalSecretsAnalyzer.js.map +1 -0
- package/dist/analyzers/universal/functionConcerns.d.ts +52 -0
- package/dist/analyzers/universal/functionConcerns.d.ts.map +1 -0
- package/dist/analyzers/universal/functionConcerns.js +225 -0
- package/dist/analyzers/universal/functionConcerns.js.map +1 -0
- package/dist/analyzers/universal/schema/codeAnalysis.d.ts.map +1 -1
- package/dist/analyzers/universal/schema/codeAnalysis.js +9 -3
- package/dist/analyzers/universal/schema/codeAnalysis.js.map +1 -1
- package/dist/analyzers/universal/schema/discovery.d.ts +29 -1
- package/dist/analyzers/universal/schema/discovery.d.ts.map +1 -1
- package/dist/analyzers/universal/schema/discovery.js +76 -21
- package/dist/analyzers/universal/schema/discovery.js.map +1 -1
- package/dist/auditRunner.d.ts.map +1 -1
- package/dist/auditRunner.js +73 -74
- package/dist/auditRunner.js.map +1 -1
- package/dist/cli.js +109 -105
- package/dist/cli.js.map +1 -1
- package/dist/codeIndexDB.js +6 -6
- package/dist/codeIndexDB.js.map +1 -1
- package/dist/config/configLoader.d.ts.map +1 -1
- package/dist/config/configLoader.js +15 -0
- package/dist/config/configLoader.js.map +1 -1
- package/dist/config/defaults.d.ts +11 -1
- package/dist/config/defaults.d.ts.map +1 -1
- package/dist/config/defaults.js +25 -3
- package/dist/config/defaults.js.map +1 -1
- package/dist/config/effectiveConfig.d.ts.map +1 -1
- package/dist/config/effectiveConfig.js +2 -0
- package/dist/config/effectiveConfig.js.map +1 -1
- package/dist/dataPaths.js +18 -1
- package/dist/dataPaths.js.map +1 -1
- package/dist/enforcement/gate.d.ts +14 -19
- package/dist/enforcement/gate.d.ts.map +1 -1
- package/dist/enforcement/gate.js +27 -45
- package/dist/enforcement/gate.js.map +1 -1
- package/dist/graph/importGraph.d.ts +11 -0
- package/dist/graph/importGraph.d.ts.map +1 -1
- package/dist/graph/importGraph.js +11 -3
- package/dist/graph/importGraph.js.map +1 -1
- package/dist/installer.d.ts.map +1 -1
- package/dist/installer.js +2 -5
- package/dist/installer.js.map +1 -1
- package/dist/mcp.js +1 -1
- package/dist/mcp.js.map +1 -1
- package/dist/pipeline.d.ts.map +1 -1
- package/dist/pipeline.js +21 -3
- package/dist/pipeline.js.map +1 -1
- package/dist/pipelineAdapters.d.ts +1 -0
- package/dist/pipelineAdapters.d.ts.map +1 -1
- package/dist/pipelineAdapters.js +227 -4
- package/dist/pipelineAdapters.js.map +1 -1
- package/dist/styles/styleExtractor.js +2 -2
- package/dist/styles/styleExtractor.js.map +1 -1
- package/dist/styles/styleIndexer.js +7 -6
- package/dist/styles/styleIndexer.js.map +1 -1
- package/dist/styles/tailwindProbe.d.ts +8 -0
- package/dist/styles/tailwindProbe.d.ts.map +1 -1
- package/dist/styles/tailwindProbe.js +11 -1
- package/dist/styles/tailwindProbe.js.map +1 -1
- package/dist/styles/types.d.ts +3 -2
- package/dist/styles/types.d.ts.map +1 -1
- package/dist/types/crossLanguage.d.ts +1 -0
- package/dist/types/crossLanguage.d.ts.map +1 -1
- package/dist/types.d.ts +23 -30
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +13 -4
- package/plugin/.claude-plugin/plugin.json +1 -1
- package/plugin/README.md +5 -3
- package/plugin/scripts/hook-audit.sh +20 -30
- package/plugin/scripts/hook-common.sh +63 -0
- package/plugin/scripts/hook-self-audit.sh +23 -31
- package/plugin/skills/code-auditor/SKILL-RULE-KINDS.md +4 -2
- package/plugin/skills/code-auditor/SKILL.md +20 -12
|
@@ -11,7 +11,6 @@ export const RULE_REGISTRY = {
|
|
|
11
11
|
analyzer: 'solid',
|
|
12
12
|
field: 'rule',
|
|
13
13
|
input: ['files'],
|
|
14
|
-
gating: true,
|
|
15
14
|
resolvable: true,
|
|
16
15
|
message: 'Class "{name}" has {methods} methods, exceeding the maximum of {max}. Consider splitting responsibilities.',
|
|
17
16
|
docs: 'solid/class-size',
|
|
@@ -32,7 +31,6 @@ export const RULE_REGISTRY = {
|
|
|
32
31
|
analyzer: 'solid',
|
|
33
32
|
field: 'rule',
|
|
34
33
|
input: ['files'],
|
|
35
|
-
gating: false,
|
|
36
34
|
resolvable: false,
|
|
37
35
|
message: 'Method "{name}" has cyclomatic complexity {complexity}, exceeding the maximum of {max}.',
|
|
38
36
|
docs: 'solid/method-complexity',
|
|
@@ -50,7 +48,6 @@ export const RULE_REGISTRY = {
|
|
|
50
48
|
analyzer: 'solid',
|
|
51
49
|
field: 'rule',
|
|
52
50
|
input: ['files'],
|
|
53
|
-
gating: false,
|
|
54
51
|
resolvable: false,
|
|
55
52
|
message: 'Class "{name}" violates the Open/Closed Principle.',
|
|
56
53
|
docs: 'solid/open-closed',
|
|
@@ -68,11 +65,12 @@ export const RULE_REGISTRY = {
|
|
|
68
65
|
analyzer: 'solid',
|
|
69
66
|
field: 'rule',
|
|
70
67
|
input: ['files'],
|
|
71
|
-
gating: true,
|
|
72
68
|
resolvable: true,
|
|
73
|
-
message: 'Function "{name}"
|
|
69
|
+
message: 'Function "{name}" mixes unrelated responsibilities. Split it into one function per concern.',
|
|
74
70
|
docs: 'solid/single-responsibility',
|
|
75
|
-
|
|
71
|
+
// #131: the mixed-concern check has no tunable threshold. The size proxies
|
|
72
|
+
// (line count, parameter count) moved to function-length / parameter-count.
|
|
73
|
+
thresholds: [],
|
|
76
74
|
samples: {
|
|
77
75
|
valid: [
|
|
78
76
|
{ code: 'function parse(input) {\n return input.trim().split(",");\n}', nearMiss: true },
|
|
@@ -85,11 +83,50 @@ export const RULE_REGISTRY = {
|
|
|
85
83
|
],
|
|
86
84
|
},
|
|
87
85
|
},
|
|
86
|
+
'function-length': {
|
|
87
|
+
analyzer: 'solid',
|
|
88
|
+
field: 'rule',
|
|
89
|
+
input: ['files'],
|
|
90
|
+
resolvable: true,
|
|
91
|
+
message: 'Function "{name}" has {lines} lines, exceeding the maximum of {max}. Consider breaking it down.',
|
|
92
|
+
docs: 'function-length',
|
|
93
|
+
thresholds: ['maxLinesPerMethod'],
|
|
94
|
+
samples: {
|
|
95
|
+
valid: [
|
|
96
|
+
{ code: 'function short(x) {\n const a = transform(x);\n const b = validate(a);\n return b;\n}', nearMiss: true },
|
|
97
|
+
],
|
|
98
|
+
invalid: [
|
|
99
|
+
{
|
|
100
|
+
code: 'function long(input) {\n let a = step1(input);\n let b = step2(a);\n let c = step3(b);\n let d = step4(c);\n let e = step5(d);\n let f = step6(e);\n let g = step7(f);\n let h = step8(g);\n let i = step9(h);\n let j = step10(i);\n let k = step11(j);\n let l = step12(k);\n let m = step13(l);\n let n = step14(m);\n let o = step15(n);\n let p = step16(o);\n let q = step17(p);\n let r = step18(q);\n let s = step19(r);\n let t = step20(s);\n let u = step21(t);\n let v = step22(u);\n let w = step23(v);\n let x = step24(w);\n let y = step25(x);\n let z = step26(y);\n let aa = step27(z);\n let ab = step28(aa);\n let ac = step29(ab);\n let ad = step30(ac);\n let ae = step31(ad);\n let af = step32(ae);\n let ag = step33(af);\n let ah = step34(ag);\n let ai = step35(ah);\n let aj = step36(ai);\n let ak = step37(aj);\n let al = step38(ak);\n let am = step39(al);\n let an = step40(am);\n let ao = step41(an);\n let ap = step42(ao);\n let aq = step43(ap);\n let ar = step44(aq);\n let as = step45(ar);\n let at = step46(as);\n let au = step47(at);\n let av = step48(au);\n let aw = step49(av);\n let ax = step50(aw);\n let ay = step51(ax);\n return ay;\n}',
|
|
101
|
+
resolution: { action: 'break-down-function', summary: 'Break "long" into smaller functions, extracting named helper blocks for each pipeline stage.', symbols: ['long'] },
|
|
102
|
+
},
|
|
103
|
+
],
|
|
104
|
+
},
|
|
105
|
+
},
|
|
106
|
+
'parameter-count': {
|
|
107
|
+
analyzer: 'solid',
|
|
108
|
+
field: 'rule',
|
|
109
|
+
input: ['files'],
|
|
110
|
+
resolvable: true,
|
|
111
|
+
message: 'Function "{name}" has {params} parameters, exceeding the maximum of {max}. Consider using an options object.',
|
|
112
|
+
docs: 'parameter-count',
|
|
113
|
+
thresholds: ['maxParametersPerMethod'],
|
|
114
|
+
samples: {
|
|
115
|
+
valid: [
|
|
116
|
+
{ code: 'function combine(a, b, c, d) {\n return a + b + c + d;\n}', nearMiss: true },
|
|
117
|
+
],
|
|
118
|
+
invalid: [
|
|
119
|
+
{
|
|
120
|
+
code: 'function combine(a, b, c, d, e) {\n return a + b + c + d + e;\n}',
|
|
121
|
+
resolution: { action: 'bundle-params', summary: 'Bundle the 5 parameters of "combine" into an options object.', symbols: ['a', 'b', 'c', 'd', 'e'] },
|
|
122
|
+
},
|
|
123
|
+
],
|
|
124
|
+
},
|
|
125
|
+
},
|
|
88
126
|
'solid/interface-segregation': {
|
|
89
127
|
analyzer: 'solid',
|
|
90
128
|
field: 'rule',
|
|
91
129
|
input: ['files'],
|
|
92
|
-
gating: false,
|
|
93
130
|
resolvable: false,
|
|
94
131
|
message: 'Interface "{name}" has many members.',
|
|
95
132
|
docs: 'solid/interface-segregation',
|
|
@@ -107,7 +144,6 @@ export const RULE_REGISTRY = {
|
|
|
107
144
|
analyzer: 'solid',
|
|
108
145
|
field: 'rule',
|
|
109
146
|
input: ['files'],
|
|
110
|
-
gating: false,
|
|
111
147
|
resolvable: false,
|
|
112
148
|
message: 'Method "{name}" overrides a parent method and throws where the parent does not.',
|
|
113
149
|
docs: 'solid/liskov-substitution',
|
|
@@ -125,7 +161,6 @@ export const RULE_REGISTRY = {
|
|
|
125
161
|
analyzer: 'solid',
|
|
126
162
|
field: 'rule',
|
|
127
163
|
input: ['files'],
|
|
128
|
-
gating: false,
|
|
129
164
|
resolvable: false,
|
|
130
165
|
message: 'Module "{name}" violates the Dependency Inversion Principle.',
|
|
131
166
|
docs: 'solid/dependency-inversion',
|
|
@@ -144,7 +179,6 @@ export const RULE_REGISTRY = {
|
|
|
144
179
|
analyzer: 'dry',
|
|
145
180
|
field: 'rule',
|
|
146
181
|
input: ['files'],
|
|
147
|
-
gating: true,
|
|
148
182
|
resolvable: true,
|
|
149
183
|
message: 'Duplicate code block detected ({lines} lines). First occurrence at {file}:{line}.',
|
|
150
184
|
docs: 'dry/duplicate',
|
|
@@ -166,7 +200,6 @@ export const RULE_REGISTRY = {
|
|
|
166
200
|
field: 'rule',
|
|
167
201
|
configGate: 'checkStructuralSimilarity',
|
|
168
202
|
input: ['files'],
|
|
169
|
-
gating: false,
|
|
170
203
|
resolvable: false,
|
|
171
204
|
message: 'Structurally similar code block detected ({similarity}% similar to {file}:{line}).',
|
|
172
205
|
docs: 'dry/structural-similarity',
|
|
@@ -180,12 +213,47 @@ export const RULE_REGISTRY = {
|
|
|
180
213
|
],
|
|
181
214
|
},
|
|
182
215
|
},
|
|
216
|
+
'dry/similar-expression': {
|
|
217
|
+
analyzer: 'dry',
|
|
218
|
+
field: 'rule',
|
|
219
|
+
configGate: 'checkExpressionSimilarity',
|
|
220
|
+
input: ['files'],
|
|
221
|
+
resolvable: true,
|
|
222
|
+
message: 'Near-identical expression detected ({shared} shared {unit}: {names}). First occurrence at {file}:{line}.',
|
|
223
|
+
docs: 'dry/similar-expression',
|
|
224
|
+
// #133: on by default. The floor (minShapeNames) counts the field/method
|
|
225
|
+
// names two fragments must share. Fluent library/builder chains (query and
|
|
226
|
+
// schema builders, Zod validators, commander, promises, DOM and stdlib
|
|
227
|
+
// method chains) are excluded and object literals must target the same
|
|
228
|
+
// identifier, so default-on stays quiet on idiomatic API surface and schema
|
|
229
|
+
// literals while still firing on the `resultSummary` object built twice.
|
|
230
|
+
thresholds: ['minShapeNames'],
|
|
231
|
+
samples: {
|
|
232
|
+
valid: [
|
|
233
|
+
{
|
|
234
|
+
// Same target assigned twice, but the field lists share nothing — a
|
|
235
|
+
// "built twice" shape that is not actually near-identical.
|
|
236
|
+
code: 'const state = {};\nstate.summary = { a: 1, b: 2, c: 3, d: 4 };\nstate.summary = { e: 5, f: 6, g: 7, h: 8 };',
|
|
237
|
+
nearMiss: true,
|
|
238
|
+
},
|
|
239
|
+
],
|
|
240
|
+
invalid: [
|
|
241
|
+
{
|
|
242
|
+
code: 'const info = {};\ninfo.resultSummary = { completedAt: now, tables: t, tableCounts: tc, stagingCounts: sc, steps: st };\ninfo.resultSummary = { completedAt: now, tables: t, tableCounts: tc, stagingCounts: sc, steps: st, durationMs: d };',
|
|
243
|
+
resolution: {
|
|
244
|
+
action: 'extract-shared-expression',
|
|
245
|
+
summary: 'Extract the shared field list (completedAt, tables, tableCounts, stagingCounts, steps) into a shared builder or constant both sites use.',
|
|
246
|
+
symbols: ['info.resultSummary'],
|
|
247
|
+
},
|
|
248
|
+
},
|
|
249
|
+
],
|
|
250
|
+
},
|
|
251
|
+
},
|
|
183
252
|
'duplicate-string-literal': {
|
|
184
253
|
analyzer: 'dry',
|
|
185
254
|
field: 'rule',
|
|
186
255
|
configGate: 'checkStrings',
|
|
187
256
|
input: ['files'],
|
|
188
|
-
gating: false,
|
|
189
257
|
resolvable: false,
|
|
190
258
|
message: 'String literal "{text}" is duplicated {count} times.',
|
|
191
259
|
docs: 'duplicate-string-literal',
|
|
@@ -204,7 +272,6 @@ export const RULE_REGISTRY = {
|
|
|
204
272
|
field: 'rule',
|
|
205
273
|
configGate: 'checkImports',
|
|
206
274
|
input: ['files'],
|
|
207
|
-
gating: false,
|
|
208
275
|
resolvable: false,
|
|
209
276
|
message: 'Duplicate import of "{module}".',
|
|
210
277
|
docs: 'duplicate-import',
|
|
@@ -223,7 +290,6 @@ export const RULE_REGISTRY = {
|
|
|
223
290
|
analyzer: 'data-access',
|
|
224
291
|
field: 'rule',
|
|
225
292
|
input: ['files'],
|
|
226
|
-
gating: true,
|
|
227
293
|
resolvable: true,
|
|
228
294
|
message: 'Potential SQL injection risk in {method}. Use parameterized queries.',
|
|
229
295
|
docs: 'sql-injection-risk',
|
|
@@ -244,7 +310,6 @@ export const RULE_REGISTRY = {
|
|
|
244
310
|
analyzer: 'data-access',
|
|
245
311
|
field: 'rule',
|
|
246
312
|
input: ['schema'],
|
|
247
|
-
gating: false,
|
|
248
313
|
resolvable: false,
|
|
249
314
|
message: 'Query on {tables} is missing an organization/tenant filter.',
|
|
250
315
|
docs: 'missing-org-filter',
|
|
@@ -262,7 +327,6 @@ export const RULE_REGISTRY = {
|
|
|
262
327
|
analyzer: 'data-access',
|
|
263
328
|
field: 'rule',
|
|
264
329
|
input: ['files'],
|
|
265
|
-
gating: false,
|
|
266
330
|
resolvable: false,
|
|
267
331
|
message: 'Query references {tables} tables.',
|
|
268
332
|
docs: 'complex-query',
|
|
@@ -280,7 +344,6 @@ export const RULE_REGISTRY = {
|
|
|
280
344
|
analyzer: 'data-access',
|
|
281
345
|
field: 'rule',
|
|
282
346
|
input: ['files'],
|
|
283
|
-
gating: false,
|
|
284
347
|
resolvable: false,
|
|
285
348
|
message: 'Query on {tables} has no filter.',
|
|
286
349
|
docs: 'unfiltered-query',
|
|
@@ -298,7 +361,6 @@ export const RULE_REGISTRY = {
|
|
|
298
361
|
analyzer: 'data-access',
|
|
299
362
|
field: 'rule',
|
|
300
363
|
input: ['files'],
|
|
301
|
-
gating: false,
|
|
302
364
|
resolvable: false,
|
|
303
365
|
message: 'Hardcoded database connection string detected.',
|
|
304
366
|
docs: 'hardcoded-connection',
|
|
@@ -316,7 +378,6 @@ export const RULE_REGISTRY = {
|
|
|
316
378
|
analyzer: 'data-access',
|
|
317
379
|
field: 'rule',
|
|
318
380
|
input: ['files'],
|
|
319
|
-
gating: false,
|
|
320
381
|
resolvable: false,
|
|
321
382
|
message: 'Database query inside a loop detected in {method}.',
|
|
322
383
|
docs: 'loop-query',
|
|
@@ -330,12 +391,47 @@ export const RULE_REGISTRY = {
|
|
|
330
391
|
],
|
|
331
392
|
},
|
|
332
393
|
},
|
|
394
|
+
// ── secrets (UniversalSecretsAnalyzer) ──────────────────────────────────
|
|
395
|
+
'hardcoded-secret': {
|
|
396
|
+
analyzer: 'secrets',
|
|
397
|
+
field: 'rule',
|
|
398
|
+
configGate: 'checkHardcodedSecrets',
|
|
399
|
+
input: ['files'],
|
|
400
|
+
resolvable: true,
|
|
401
|
+
message: 'Hardcoded secret detected: a credential value is embedded in source. Move it to an environment variable or secret store.',
|
|
402
|
+
docs: 'hardcoded-secret',
|
|
403
|
+
thresholds: [],
|
|
404
|
+
samples: {
|
|
405
|
+
valid: [
|
|
406
|
+
// Placeholder value — named like a secret, but the value is a known placeholder.
|
|
407
|
+
{ code: "const apiKey = 'your-api-key';", nearMiss: true },
|
|
408
|
+
// Env var reference — not a string literal, so never a candidate.
|
|
409
|
+
{ code: 'const apiKey = process.env.API_KEY;', nearMiss: true },
|
|
410
|
+
],
|
|
411
|
+
invalid: [
|
|
412
|
+
{
|
|
413
|
+
code: "const password = 'hunter2Secret9';",
|
|
414
|
+
resolution: {
|
|
415
|
+
action: 'remove-hardcoded-secret',
|
|
416
|
+
summary: 'Replace the hardcoded "password" credential with a reference to an environment variable or secret store (e.g. process.env.PASSWORD).',
|
|
417
|
+
symbols: ['password'],
|
|
418
|
+
},
|
|
419
|
+
},
|
|
420
|
+
{
|
|
421
|
+
code: "await page.type('#password', 'vyy8AUVvish34Fq');",
|
|
422
|
+
resolution: {
|
|
423
|
+
action: 'remove-hardcoded-secret',
|
|
424
|
+
summary: 'Replace the hardcoded credential with a reference to an environment variable or secret store (e.g. process.env.SECRET).',
|
|
425
|
+
},
|
|
426
|
+
},
|
|
427
|
+
],
|
|
428
|
+
},
|
|
429
|
+
},
|
|
333
430
|
// ── documentation (UniversalDocumentationAnalyzer) ─────────────────────
|
|
334
431
|
'file-documentation': {
|
|
335
432
|
analyzer: 'documentation',
|
|
336
433
|
field: 'rule',
|
|
337
434
|
input: ['files'],
|
|
338
|
-
gating: false,
|
|
339
435
|
resolvable: false,
|
|
340
436
|
message: 'File is missing a leading documentation comment.',
|
|
341
437
|
docs: 'file-documentation',
|
|
@@ -353,7 +449,6 @@ export const RULE_REGISTRY = {
|
|
|
353
449
|
analyzer: 'documentation',
|
|
354
450
|
field: 'rule',
|
|
355
451
|
input: ['files'],
|
|
356
|
-
gating: false,
|
|
357
452
|
resolvable: false,
|
|
358
453
|
message: 'Function "{name}" is missing a doc comment.',
|
|
359
454
|
docs: 'function-documentation',
|
|
@@ -371,7 +466,6 @@ export const RULE_REGISTRY = {
|
|
|
371
466
|
analyzer: 'documentation',
|
|
372
467
|
field: 'rule',
|
|
373
468
|
input: ['files'],
|
|
374
|
-
gating: false,
|
|
375
469
|
resolvable: false,
|
|
376
470
|
message: 'Parameter "{name}" in function "{func}" is missing a @param tag.',
|
|
377
471
|
docs: 'parameter-documentation',
|
|
@@ -389,7 +483,6 @@ export const RULE_REGISTRY = {
|
|
|
389
483
|
analyzer: 'documentation',
|
|
390
484
|
field: 'rule',
|
|
391
485
|
input: ['files'],
|
|
392
|
-
gating: false,
|
|
393
486
|
resolvable: false,
|
|
394
487
|
message: 'Function "{name}" is missing a @returns tag.',
|
|
395
488
|
docs: 'return-documentation',
|
|
@@ -407,7 +500,6 @@ export const RULE_REGISTRY = {
|
|
|
407
500
|
analyzer: 'documentation',
|
|
408
501
|
field: 'rule',
|
|
409
502
|
input: ['files'],
|
|
410
|
-
gating: false,
|
|
411
503
|
resolvable: false,
|
|
412
504
|
message: 'Class "{name}" is missing a doc comment.',
|
|
413
505
|
docs: 'class-documentation',
|
|
@@ -425,7 +517,6 @@ export const RULE_REGISTRY = {
|
|
|
425
517
|
analyzer: 'documentation',
|
|
426
518
|
field: 'rule',
|
|
427
519
|
input: ['files'],
|
|
428
|
-
gating: false,
|
|
429
520
|
resolvable: false,
|
|
430
521
|
message: 'Method "{name}" is missing a doc comment.',
|
|
431
522
|
docs: 'method-documentation',
|
|
@@ -445,7 +536,6 @@ export const RULE_REGISTRY = {
|
|
|
445
536
|
analyzer: 'schema',
|
|
446
537
|
field: 'rule',
|
|
447
538
|
input: ['schema-json'],
|
|
448
|
-
gating: false,
|
|
449
539
|
resolvable: false,
|
|
450
540
|
message: 'Invalid JSON: {error}.',
|
|
451
541
|
docs: 'invalid-json',
|
|
@@ -463,7 +553,6 @@ export const RULE_REGISTRY = {
|
|
|
463
553
|
analyzer: 'schema',
|
|
464
554
|
field: 'rule',
|
|
465
555
|
input: ['schema-json'],
|
|
466
|
-
gating: false,
|
|
467
556
|
resolvable: false,
|
|
468
557
|
message: 'Missing JSON schema declaration.',
|
|
469
558
|
docs: 'missing-schema-declaration',
|
|
@@ -481,7 +570,6 @@ export const RULE_REGISTRY = {
|
|
|
481
570
|
analyzer: 'schema',
|
|
482
571
|
field: 'rule',
|
|
483
572
|
input: ['schema-json'],
|
|
484
|
-
gating: false,
|
|
485
573
|
resolvable: false,
|
|
486
574
|
message: 'Undefined required field "{field}".',
|
|
487
575
|
docs: 'undefined-required-field',
|
|
@@ -499,7 +587,6 @@ export const RULE_REGISTRY = {
|
|
|
499
587
|
analyzer: 'schema',
|
|
500
588
|
field: 'rule',
|
|
501
589
|
input: ['schema-json'],
|
|
502
|
-
gating: false,
|
|
503
590
|
resolvable: false,
|
|
504
591
|
message: 'Invalid type for field "{field}".',
|
|
505
592
|
docs: 'invalid-type',
|
|
@@ -517,7 +604,6 @@ export const RULE_REGISTRY = {
|
|
|
517
604
|
analyzer: 'schema',
|
|
518
605
|
field: 'rule',
|
|
519
606
|
input: ['schema-json'],
|
|
520
|
-
gating: false,
|
|
521
607
|
resolvable: false,
|
|
522
608
|
message: 'Invalid range for field "{field}".',
|
|
523
609
|
docs: 'invalid-range',
|
|
@@ -535,7 +621,6 @@ export const RULE_REGISTRY = {
|
|
|
535
621
|
analyzer: 'schema',
|
|
536
622
|
field: 'rule',
|
|
537
623
|
input: ['schema-json'],
|
|
538
|
-
gating: false,
|
|
539
624
|
resolvable: false,
|
|
540
625
|
message: 'Error processing schema file: {error}.',
|
|
541
626
|
docs: 'file-error',
|
|
@@ -553,7 +638,6 @@ export const RULE_REGISTRY = {
|
|
|
553
638
|
analyzer: 'schema',
|
|
554
639
|
field: 'rule',
|
|
555
640
|
input: ['schema-json'],
|
|
556
|
-
gating: false,
|
|
557
641
|
resolvable: false,
|
|
558
642
|
message: 'Type mismatch for field "{field}".',
|
|
559
643
|
docs: 'type-mismatch',
|
|
@@ -571,7 +655,6 @@ export const RULE_REGISTRY = {
|
|
|
571
655
|
analyzer: 'schema',
|
|
572
656
|
field: 'rule',
|
|
573
657
|
input: ['schema-json'],
|
|
574
|
-
gating: false,
|
|
575
658
|
resolvable: false,
|
|
576
659
|
message: 'String value too short for field "{field}".',
|
|
577
660
|
docs: 'string-too-short',
|
|
@@ -589,7 +672,6 @@ export const RULE_REGISTRY = {
|
|
|
589
672
|
analyzer: 'schema',
|
|
590
673
|
field: 'rule',
|
|
591
674
|
input: ['schema-json'],
|
|
592
|
-
gating: false,
|
|
593
675
|
resolvable: false,
|
|
594
676
|
message: 'String value too long for field "{field}".',
|
|
595
677
|
docs: 'string-too-long',
|
|
@@ -607,7 +689,6 @@ export const RULE_REGISTRY = {
|
|
|
607
689
|
analyzer: 'schema',
|
|
608
690
|
field: 'rule',
|
|
609
691
|
input: ['schema-json'],
|
|
610
|
-
gating: false,
|
|
611
692
|
resolvable: false,
|
|
612
693
|
message: 'Value does not match pattern for field "{field}".',
|
|
613
694
|
docs: 'pattern-mismatch',
|
|
@@ -625,7 +706,6 @@ export const RULE_REGISTRY = {
|
|
|
625
706
|
analyzer: 'schema',
|
|
626
707
|
field: 'rule',
|
|
627
708
|
input: ['schema-json'],
|
|
628
|
-
gating: false,
|
|
629
709
|
resolvable: false,
|
|
630
710
|
message: 'Invalid format for field "{field}".',
|
|
631
711
|
docs: 'invalid-format',
|
|
@@ -643,7 +723,6 @@ export const RULE_REGISTRY = {
|
|
|
643
723
|
analyzer: 'schema',
|
|
644
724
|
field: 'rule',
|
|
645
725
|
input: ['schema-json'],
|
|
646
|
-
gating: false,
|
|
647
726
|
resolvable: false,
|
|
648
727
|
message: 'Value below minimum for field "{field}".',
|
|
649
728
|
docs: 'below-minimum',
|
|
@@ -661,7 +740,6 @@ export const RULE_REGISTRY = {
|
|
|
661
740
|
analyzer: 'schema',
|
|
662
741
|
field: 'rule',
|
|
663
742
|
input: ['schema-json'],
|
|
664
|
-
gating: false,
|
|
665
743
|
resolvable: false,
|
|
666
744
|
message: 'Value above maximum for field "{field}".',
|
|
667
745
|
docs: 'above-maximum',
|
|
@@ -679,7 +757,6 @@ export const RULE_REGISTRY = {
|
|
|
679
757
|
analyzer: 'schema',
|
|
680
758
|
field: 'rule',
|
|
681
759
|
input: ['schema-json'],
|
|
682
|
-
gating: false,
|
|
683
760
|
resolvable: false,
|
|
684
761
|
message: 'Too few items for field "{field}".',
|
|
685
762
|
docs: 'too-few-items',
|
|
@@ -697,7 +774,6 @@ export const RULE_REGISTRY = {
|
|
|
697
774
|
analyzer: 'schema',
|
|
698
775
|
field: 'rule',
|
|
699
776
|
input: ['schema-json'],
|
|
700
|
-
gating: false,
|
|
701
777
|
resolvable: false,
|
|
702
778
|
message: 'Too many items for field "{field}".',
|
|
703
779
|
docs: 'too-many-items',
|
|
@@ -715,7 +791,6 @@ export const RULE_REGISTRY = {
|
|
|
715
791
|
analyzer: 'schema',
|
|
716
792
|
field: 'rule',
|
|
717
793
|
input: ['schema-json'],
|
|
718
|
-
gating: false,
|
|
719
794
|
resolvable: false,
|
|
720
795
|
message: 'Missing required field "{field}".',
|
|
721
796
|
docs: 'missing-required-field',
|
|
@@ -733,7 +808,6 @@ export const RULE_REGISTRY = {
|
|
|
733
808
|
analyzer: 'schema',
|
|
734
809
|
field: 'rule',
|
|
735
810
|
input: ['schema-json'],
|
|
736
|
-
gating: false,
|
|
737
811
|
resolvable: false,
|
|
738
812
|
message: 'Unexpected property "{property}".',
|
|
739
813
|
docs: 'unexpected-property',
|
|
@@ -751,7 +825,6 @@ export const RULE_REGISTRY = {
|
|
|
751
825
|
analyzer: 'schema',
|
|
752
826
|
field: 'rule',
|
|
753
827
|
input: ['schema-json'],
|
|
754
|
-
gating: false,
|
|
755
828
|
resolvable: false,
|
|
756
829
|
message: 'Value does not match any enum value for field "{field}".',
|
|
757
830
|
docs: 'enum-mismatch',
|
|
@@ -770,7 +843,6 @@ export const RULE_REGISTRY = {
|
|
|
770
843
|
analyzer: 'schema',
|
|
771
844
|
field: 'rule',
|
|
772
845
|
input: ['schema-code'],
|
|
773
|
-
gating: false,
|
|
774
846
|
resolvable: false,
|
|
775
847
|
message: 'Potential SQL injection via string interpolation in {method}.',
|
|
776
848
|
docs: 'sql-injection',
|
|
@@ -791,7 +863,6 @@ export const RULE_REGISTRY = {
|
|
|
791
863
|
field: 'rule',
|
|
792
864
|
configGate: 'checkNamingConventions',
|
|
793
865
|
input: ['schema-code'],
|
|
794
|
-
gating: false,
|
|
795
866
|
resolvable: false,
|
|
796
867
|
message: 'Table name "{table}" should use snake_case convention.',
|
|
797
868
|
docs: 'table-naming-convention',
|
|
@@ -810,7 +881,6 @@ export const RULE_REGISTRY = {
|
|
|
810
881
|
analyzer: 'schema',
|
|
811
882
|
field: 'rule',
|
|
812
883
|
input: ['schema-code'],
|
|
813
|
-
gating: true,
|
|
814
884
|
resolvable: true,
|
|
815
885
|
message: 'Reference to unknown table "{table}" ({type}). Did you mean: {suggestions}?',
|
|
816
886
|
docs: 'unknown-table',
|
|
@@ -832,7 +902,6 @@ export const RULE_REGISTRY = {
|
|
|
832
902
|
analyzer: 'react',
|
|
833
903
|
field: 'rule',
|
|
834
904
|
input: ['files'],
|
|
835
|
-
gating: false,
|
|
836
905
|
resolvable: false,
|
|
837
906
|
message: 'React hook "{name}" does not follow the "use*" naming convention.',
|
|
838
907
|
docs: 'hooks-naming',
|
|
@@ -850,7 +919,6 @@ export const RULE_REGISTRY = {
|
|
|
850
919
|
analyzer: 'react',
|
|
851
920
|
field: 'rule',
|
|
852
921
|
input: ['files'],
|
|
853
|
-
gating: false,
|
|
854
922
|
resolvable: false,
|
|
855
923
|
message: 'React component "{name}" has complexity {complexity}, exceeding the maximum.',
|
|
856
924
|
docs: 'complexity',
|
|
@@ -869,7 +937,6 @@ export const RULE_REGISTRY = {
|
|
|
869
937
|
field: 'rule',
|
|
870
938
|
configGate: 'requirePropTypes',
|
|
871
939
|
input: ['files'],
|
|
872
|
-
gating: false,
|
|
873
940
|
resolvable: false,
|
|
874
941
|
message: 'React component "{name}" is missing prop-types.',
|
|
875
942
|
docs: 'missing-props',
|
|
@@ -887,7 +954,6 @@ export const RULE_REGISTRY = {
|
|
|
887
954
|
analyzer: 'react',
|
|
888
955
|
field: 'rule',
|
|
889
956
|
input: ['files'],
|
|
890
|
-
gating: false,
|
|
891
957
|
resolvable: false,
|
|
892
958
|
message: 'React component tree is missing an error boundary.',
|
|
893
959
|
docs: 'no-error-boundary',
|
|
@@ -906,7 +972,6 @@ export const RULE_REGISTRY = {
|
|
|
906
972
|
field: 'rule',
|
|
907
973
|
configGate: 'requireMemoization',
|
|
908
974
|
input: ['files'],
|
|
909
|
-
gating: false,
|
|
910
975
|
resolvable: false,
|
|
911
976
|
message: 'React component "{name}" is missing memoization.',
|
|
912
977
|
docs: 'performance',
|
|
@@ -924,7 +989,6 @@ export const RULE_REGISTRY = {
|
|
|
924
989
|
analyzer: 'react',
|
|
925
990
|
field: 'rule',
|
|
926
991
|
input: ['files'],
|
|
927
|
-
gating: false,
|
|
928
992
|
resolvable: false,
|
|
929
993
|
message: 'Accessibility issue in component "{name}": {issue}.',
|
|
930
994
|
docs: 'accessibility',
|
|
@@ -942,7 +1006,6 @@ export const RULE_REGISTRY = {
|
|
|
942
1006
|
analyzer: 'react',
|
|
943
1007
|
field: 'rule',
|
|
944
1008
|
input: ['files'],
|
|
945
|
-
gating: true,
|
|
946
1009
|
resolvable: true,
|
|
947
1010
|
message: 'raw `<{element}>` — this project uses `<{wrapper}>` ({file}).',
|
|
948
1011
|
docs: 'raw-element',
|
|
@@ -965,7 +1028,6 @@ export const RULE_REGISTRY = {
|
|
|
965
1028
|
analyzer: 'invariants',
|
|
966
1029
|
field: 'rule',
|
|
967
1030
|
input: ['files'],
|
|
968
|
-
gating: false,
|
|
969
1031
|
resolvable: false,
|
|
970
1032
|
message: 'Invalid invariant config: {error}.',
|
|
971
1033
|
docs: 'config-error',
|
|
@@ -983,7 +1045,6 @@ export const RULE_REGISTRY = {
|
|
|
983
1045
|
analyzer: 'invariants',
|
|
984
1046
|
field: 'rule',
|
|
985
1047
|
input: ['files'],
|
|
986
|
-
gating: false,
|
|
987
1048
|
resolvable: false,
|
|
988
1049
|
message: 'Invariant rule engine error: {error}.',
|
|
989
1050
|
docs: 'engine-error',
|
|
@@ -1002,7 +1063,6 @@ export const RULE_REGISTRY = {
|
|
|
1002
1063
|
analyzer: 'schema-validator',
|
|
1003
1064
|
field: 'rule',
|
|
1004
1065
|
input: ['cross-language-entities'],
|
|
1005
|
-
gating: false,
|
|
1006
1066
|
resolvable: false,
|
|
1007
1067
|
message: 'Field mismatch: {detail}.',
|
|
1008
1068
|
docs: 'field-mismatch',
|
|
@@ -1020,7 +1080,6 @@ export const RULE_REGISTRY = {
|
|
|
1020
1080
|
analyzer: 'schema-validator',
|
|
1021
1081
|
field: 'rule',
|
|
1022
1082
|
input: ['cross-language-entities'],
|
|
1023
|
-
gating: false,
|
|
1024
1083
|
resolvable: false,
|
|
1025
1084
|
message: 'Schema field type-name strings differ: {detail}.',
|
|
1026
1085
|
docs: 'schema-field-mismatch',
|
|
@@ -1038,7 +1097,6 @@ export const RULE_REGISTRY = {
|
|
|
1038
1097
|
analyzer: 'schema-validator',
|
|
1039
1098
|
field: 'rule',
|
|
1040
1099
|
input: ['cross-language-entities'],
|
|
1041
|
-
gating: false,
|
|
1042
1100
|
resolvable: false,
|
|
1043
1101
|
message: 'Missing field: {field}.',
|
|
1044
1102
|
docs: 'missing-field',
|
|
@@ -1056,7 +1114,6 @@ export const RULE_REGISTRY = {
|
|
|
1056
1114
|
analyzer: 'schema-validator',
|
|
1057
1115
|
field: 'rule',
|
|
1058
1116
|
input: ['cross-language-entities'],
|
|
1059
|
-
gating: false,
|
|
1060
1117
|
resolvable: false,
|
|
1061
1118
|
message: 'Extra field: {field}.',
|
|
1062
1119
|
docs: 'extra-field',
|
|
@@ -1074,7 +1131,6 @@ export const RULE_REGISTRY = {
|
|
|
1074
1131
|
analyzer: 'schema-validator',
|
|
1075
1132
|
field: 'rule',
|
|
1076
1133
|
input: ['cross-language-entities'],
|
|
1077
|
-
gating: false,
|
|
1078
1134
|
resolvable: false,
|
|
1079
1135
|
message: 'Constraint mismatch: {detail}.',
|
|
1080
1136
|
docs: 'constraint-mismatch',
|
|
@@ -1092,7 +1148,6 @@ export const RULE_REGISTRY = {
|
|
|
1092
1148
|
analyzer: 'schema-validator',
|
|
1093
1149
|
field: 'rule',
|
|
1094
1150
|
input: ['cross-language-entities'],
|
|
1095
|
-
gating: false,
|
|
1096
1151
|
resolvable: false,
|
|
1097
1152
|
message: 'Version mismatch: {detail}.',
|
|
1098
1153
|
docs: 'version-mismatch',
|
|
@@ -1111,7 +1166,6 @@ export const RULE_REGISTRY = {
|
|
|
1111
1166
|
analyzer: 'api-contract',
|
|
1112
1167
|
field: 'rule',
|
|
1113
1168
|
input: ['cross-language-entities'],
|
|
1114
|
-
gating: false,
|
|
1115
1169
|
resolvable: false,
|
|
1116
1170
|
message: 'API type mismatch: {detail}.',
|
|
1117
1171
|
docs: 'api-type-mismatch',
|
|
@@ -1129,7 +1183,6 @@ export const RULE_REGISTRY = {
|
|
|
1129
1183
|
analyzer: 'api-contract',
|
|
1130
1184
|
field: 'rule',
|
|
1131
1185
|
input: ['cross-language-entities'],
|
|
1132
|
-
gating: false,
|
|
1133
1186
|
resolvable: false,
|
|
1134
1187
|
message: 'Missing API endpoint: {endpoint}.',
|
|
1135
1188
|
docs: 'missing-endpoint',
|
|
@@ -1147,7 +1200,6 @@ export const RULE_REGISTRY = {
|
|
|
1147
1200
|
analyzer: 'api-contract',
|
|
1148
1201
|
field: 'rule',
|
|
1149
1202
|
input: ['cross-language-entities'],
|
|
1150
|
-
gating: false,
|
|
1151
1203
|
resolvable: false,
|
|
1152
1204
|
message: 'Extra field in API response: {field}.',
|
|
1153
1205
|
docs: 'api-extra-field',
|
|
@@ -1165,7 +1217,6 @@ export const RULE_REGISTRY = {
|
|
|
1165
1217
|
analyzer: 'api-contract',
|
|
1166
1218
|
field: 'rule',
|
|
1167
1219
|
input: ['cross-language-entities'],
|
|
1168
|
-
gating: false,
|
|
1169
1220
|
resolvable: false,
|
|
1170
1221
|
message: 'Missing field in API response: {field}.',
|
|
1171
1222
|
docs: 'api-missing-field',
|
|
@@ -1183,7 +1234,6 @@ export const RULE_REGISTRY = {
|
|
|
1183
1234
|
analyzer: 'api-contract',
|
|
1184
1235
|
field: 'rule',
|
|
1185
1236
|
input: ['cross-language-entities'],
|
|
1186
|
-
gating: false,
|
|
1187
1237
|
resolvable: false,
|
|
1188
1238
|
message: 'HTTP method mismatch: {detail}.',
|
|
1189
1239
|
docs: 'method-mismatch',
|
|
@@ -1201,7 +1251,6 @@ export const RULE_REGISTRY = {
|
|
|
1201
1251
|
analyzer: 'api-contract',
|
|
1202
1252
|
field: 'rule',
|
|
1203
1253
|
input: ['cross-language-entities'],
|
|
1204
|
-
gating: false,
|
|
1205
1254
|
resolvable: false,
|
|
1206
1255
|
message: 'Authentication mismatch: {detail}.',
|
|
1207
1256
|
docs: 'auth-mismatch',
|
|
@@ -1220,7 +1269,6 @@ export const RULE_REGISTRY = {
|
|
|
1220
1269
|
analyzer: 'dependency-graph',
|
|
1221
1270
|
field: 'type',
|
|
1222
1271
|
input: ['cross-language-entities'],
|
|
1223
|
-
gating: false,
|
|
1224
1272
|
resolvable: false,
|
|
1225
1273
|
message: 'Circular dependency detected: {cycle}.',
|
|
1226
1274
|
docs: 'circular-dependency',
|
|
@@ -1238,7 +1286,6 @@ export const RULE_REGISTRY = {
|
|
|
1238
1286
|
analyzer: 'dependency-graph',
|
|
1239
1287
|
field: 'type',
|
|
1240
1288
|
input: ['cross-language-entities'],
|
|
1241
|
-
gating: false,
|
|
1242
1289
|
resolvable: false,
|
|
1243
1290
|
message: 'Break dependency cycle: {cycle}.',
|
|
1244
1291
|
docs: 'break-cycles',
|
|
@@ -1256,7 +1303,6 @@ export const RULE_REGISTRY = {
|
|
|
1256
1303
|
analyzer: 'dependency-graph',
|
|
1257
1304
|
field: 'type',
|
|
1258
1305
|
input: ['cross-language-entities'],
|
|
1259
|
-
gating: false,
|
|
1260
1306
|
resolvable: false,
|
|
1261
1307
|
message: 'Tight coupling detected between {a} and {b}.',
|
|
1262
1308
|
docs: 'tight-coupling',
|
|
@@ -1274,7 +1320,6 @@ export const RULE_REGISTRY = {
|
|
|
1274
1320
|
analyzer: 'dependency-graph',
|
|
1275
1321
|
field: 'type',
|
|
1276
1322
|
input: ['cross-language-entities'],
|
|
1277
|
-
gating: false,
|
|
1278
1323
|
resolvable: false,
|
|
1279
1324
|
message: 'Reduce coupling between {a} and {b}.',
|
|
1280
1325
|
docs: 'reduce-coupling',
|
|
@@ -1292,7 +1337,6 @@ export const RULE_REGISTRY = {
|
|
|
1292
1337
|
analyzer: 'dependency-graph',
|
|
1293
1338
|
field: 'type',
|
|
1294
1339
|
input: ['cross-language-entities'],
|
|
1295
|
-
gating: false,
|
|
1296
1340
|
resolvable: false,
|
|
1297
1341
|
message: 'Hub node "{node}" has {count} dependencies.',
|
|
1298
1342
|
docs: 'hub-nodes',
|
|
@@ -1310,7 +1354,6 @@ export const RULE_REGISTRY = {
|
|
|
1310
1354
|
analyzer: 'dependency-graph',
|
|
1311
1355
|
field: 'type',
|
|
1312
1356
|
input: ['cross-language-entities'],
|
|
1313
|
-
gating: false,
|
|
1314
1357
|
resolvable: false,
|
|
1315
1358
|
message: 'Split responsibilities of node "{node}".',
|
|
1316
1359
|
docs: 'split-responsibilities',
|
|
@@ -1328,7 +1371,6 @@ export const RULE_REGISTRY = {
|
|
|
1328
1371
|
analyzer: 'dependency-graph',
|
|
1329
1372
|
field: 'type',
|
|
1330
1373
|
input: ['cross-language-entities'],
|
|
1331
|
-
gating: false,
|
|
1332
1374
|
resolvable: false,
|
|
1333
1375
|
message: 'Orphaned node "{node}" has no connections.',
|
|
1334
1376
|
docs: 'orphaned-nodes',
|
|
@@ -1346,7 +1388,6 @@ export const RULE_REGISTRY = {
|
|
|
1346
1388
|
analyzer: 'dependency-graph',
|
|
1347
1389
|
field: 'type',
|
|
1348
1390
|
input: ['cross-language-entities'],
|
|
1349
|
-
gating: false,
|
|
1350
1391
|
resolvable: false,
|
|
1351
1392
|
message: 'Review orphaned nodes: {nodes}.',
|
|
1352
1393
|
docs: 'review-orphans',
|
|
@@ -1360,12 +1401,28 @@ export const RULE_REGISTRY = {
|
|
|
1360
1401
|
],
|
|
1361
1402
|
},
|
|
1362
1403
|
},
|
|
1404
|
+
'unreferenced-module': {
|
|
1405
|
+
analyzer: 'dependency-graph',
|
|
1406
|
+
field: 'type',
|
|
1407
|
+
input: ['cross-language-entities'],
|
|
1408
|
+
resolvable: false,
|
|
1409
|
+
message: 'Module is not imported by any other file and is not a framework entry point — dead code candidate.',
|
|
1410
|
+
docs: 'unreferenced-module',
|
|
1411
|
+
thresholds: [],
|
|
1412
|
+
samples: {
|
|
1413
|
+
valid: [
|
|
1414
|
+
{ code: 'export function used() {}', nearMiss: true },
|
|
1415
|
+
],
|
|
1416
|
+
invalid: [
|
|
1417
|
+
{ code: '// file exports symbols but nothing imports it' },
|
|
1418
|
+
],
|
|
1419
|
+
},
|
|
1420
|
+
},
|
|
1363
1421
|
// ── styles (UniversalStylesAnalyzer) ─────────────────────────────────────
|
|
1364
1422
|
'styles/value-drift': {
|
|
1365
1423
|
analyzer: 'styles',
|
|
1366
1424
|
field: 'rule',
|
|
1367
1425
|
input: ['styles-css'],
|
|
1368
|
-
gating: false,
|
|
1369
1426
|
resolvable: false,
|
|
1370
1427
|
message: 'Color value "{value}" drifts from the dominant token.',
|
|
1371
1428
|
docs: 'styles/value-drift',
|
|
@@ -1383,7 +1440,6 @@ export const RULE_REGISTRY = {
|
|
|
1383
1440
|
analyzer: 'styles',
|
|
1384
1441
|
field: 'rule',
|
|
1385
1442
|
input: ['styles-css'],
|
|
1386
|
-
gating: false,
|
|
1387
1443
|
resolvable: false,
|
|
1388
1444
|
message: 'Value "{value}" is off the project\'s design scale.',
|
|
1389
1445
|
docs: 'styles/off-scale',
|
|
@@ -1401,7 +1457,6 @@ export const RULE_REGISTRY = {
|
|
|
1401
1457
|
analyzer: 'styles',
|
|
1402
1458
|
field: 'rule',
|
|
1403
1459
|
input: ['styles-css'],
|
|
1404
|
-
gating: true,
|
|
1405
1460
|
resolvable: true,
|
|
1406
1461
|
message: 'Undefined CSS class: "{class}" has no matching definition.',
|
|
1407
1462
|
docs: 'styles/undefined-class',
|
|
@@ -1422,7 +1477,6 @@ export const RULE_REGISTRY = {
|
|
|
1422
1477
|
analyzer: 'styles',
|
|
1423
1478
|
field: 'rule',
|
|
1424
1479
|
input: ['styles-css'],
|
|
1425
|
-
gating: false,
|
|
1426
1480
|
resolvable: false,
|
|
1427
1481
|
message: 'Undefined-class detection skipped: {reason}.',
|
|
1428
1482
|
docs: 'styles/undefined-class-disabled',
|
|
@@ -1440,7 +1494,6 @@ export const RULE_REGISTRY = {
|
|
|
1440
1494
|
analyzer: 'styles',
|
|
1441
1495
|
field: 'rule',
|
|
1442
1496
|
input: ['styles-css'],
|
|
1443
|
-
gating: false,
|
|
1444
1497
|
resolvable: false,
|
|
1445
1498
|
message: 'Token bypass: raw value "{value}" used instead of a design token.',
|
|
1446
1499
|
docs: 'styles/token-bypass',
|
|
@@ -1458,7 +1511,6 @@ export const RULE_REGISTRY = {
|
|
|
1458
1511
|
analyzer: 'styles',
|
|
1459
1512
|
field: 'rule',
|
|
1460
1513
|
input: ['styles-css'],
|
|
1461
|
-
gating: false,
|
|
1462
1514
|
resolvable: false,
|
|
1463
1515
|
message: 'Styling mechanism fragmented across {count} mechanisms.',
|
|
1464
1516
|
docs: 'styles/mechanism-fragmentation',
|
|
@@ -1476,7 +1528,6 @@ export const RULE_REGISTRY = {
|
|
|
1476
1528
|
analyzer: 'styles',
|
|
1477
1529
|
field: 'rule',
|
|
1478
1530
|
input: ['styles-css'],
|
|
1479
|
-
gating: false,
|
|
1480
1531
|
resolvable: false,
|
|
1481
1532
|
message: 'Mixing styling mechanisms in one file.',
|
|
1482
1533
|
docs: 'styles/mechanism-mixing',
|
|
@@ -1494,7 +1545,6 @@ export const RULE_REGISTRY = {
|
|
|
1494
1545
|
analyzer: 'styles',
|
|
1495
1546
|
field: 'rule',
|
|
1496
1547
|
input: ['styles-css'],
|
|
1497
|
-
gating: false,
|
|
1498
1548
|
resolvable: false,
|
|
1499
1549
|
message: 'Declaration set similar to another block ({similarity}%).',
|
|
1500
1550
|
docs: 'styles/declaration-set-similarity',
|
|
@@ -1512,7 +1562,6 @@ export const RULE_REGISTRY = {
|
|
|
1512
1562
|
analyzer: 'styles',
|
|
1513
1563
|
field: 'rule',
|
|
1514
1564
|
input: ['styles-css'],
|
|
1515
|
-
gating: false,
|
|
1516
1565
|
resolvable: false,
|
|
1517
1566
|
message: 'Z-index sprawl: {count} distinct z-index values.',
|
|
1518
1567
|
docs: 'styles/z-index-sprawl',
|
|
@@ -1530,7 +1579,6 @@ export const RULE_REGISTRY = {
|
|
|
1530
1579
|
analyzer: 'styles',
|
|
1531
1580
|
field: 'rule',
|
|
1532
1581
|
input: ['styles-css'],
|
|
1533
|
-
gating: false,
|
|
1534
1582
|
resolvable: false,
|
|
1535
1583
|
message: 'Z-index value "{value}" appears only once.',
|
|
1536
1584
|
docs: 'styles/z-index-singleton',
|
|
@@ -1549,7 +1597,6 @@ export const RULE_REGISTRY = {
|
|
|
1549
1597
|
analyzer: 'conventions',
|
|
1550
1598
|
field: 'rule',
|
|
1551
1599
|
input: ['function-index'],
|
|
1552
|
-
gating: true,
|
|
1553
1600
|
resolvable: true,
|
|
1554
1601
|
message: '{pct}% of `{antecedent}` callers also call `{consequent}`.',
|
|
1555
1602
|
docs: 'conventions/usage-pair',
|
|
@@ -1570,7 +1617,6 @@ export const RULE_REGISTRY = {
|
|
|
1570
1617
|
analyzer: 'conventions',
|
|
1571
1618
|
field: 'rule',
|
|
1572
1619
|
input: ['function-index'],
|
|
1573
|
-
gating: false,
|
|
1574
1620
|
resolvable: false,
|
|
1575
1621
|
message: 'Import form mismatch: use {form} for "{source}".',
|
|
1576
1622
|
docs: 'conventions/import-form',
|
|
@@ -1588,7 +1634,6 @@ export const RULE_REGISTRY = {
|
|
|
1588
1634
|
analyzer: 'conventions',
|
|
1589
1635
|
field: 'rule',
|
|
1590
1636
|
input: ['function-index'],
|
|
1591
|
-
gating: false,
|
|
1592
1637
|
resolvable: false,
|
|
1593
1638
|
message: 'Error-handling convention mismatch: {detail}.',
|
|
1594
1639
|
docs: 'conventions/error-handling',
|
|
@@ -1606,7 +1651,6 @@ export const RULE_REGISTRY = {
|
|
|
1606
1651
|
analyzer: 'conventions',
|
|
1607
1652
|
field: 'rule',
|
|
1608
1653
|
input: ['function-index'],
|
|
1609
|
-
gating: false,
|
|
1610
1654
|
resolvable: false,
|
|
1611
1655
|
message: 'Export shape mismatch: {detail}.',
|
|
1612
1656
|
docs: 'conventions/export-shape',
|
|
@@ -1624,7 +1668,6 @@ export const RULE_REGISTRY = {
|
|
|
1624
1668
|
analyzer: 'conventions',
|
|
1625
1669
|
field: 'rule',
|
|
1626
1670
|
input: ['function-index'],
|
|
1627
|
-
gating: false,
|
|
1628
1671
|
resolvable: false,
|
|
1629
1672
|
message: 'Naming convention mismatch: {detail}.',
|
|
1630
1673
|
docs: 'conventions/naming',
|
|
@@ -1643,7 +1686,6 @@ export const RULE_REGISTRY = {
|
|
|
1643
1686
|
analyzer: 'cross-domain',
|
|
1644
1687
|
field: 'rule',
|
|
1645
1688
|
input: ['schema_usage', 'functions'],
|
|
1646
|
-
gating: false,
|
|
1647
1689
|
resolvable: false,
|
|
1648
1690
|
message: 'Table "{table}" is written but never read.',
|
|
1649
1691
|
docs: 'cross-domain/written-never-read',
|
|
@@ -1661,7 +1703,6 @@ export const RULE_REGISTRY = {
|
|
|
1661
1703
|
analyzer: 'cross-domain',
|
|
1662
1704
|
field: 'rule',
|
|
1663
1705
|
input: ['schema_usage', 'functions'],
|
|
1664
|
-
gating: false,
|
|
1665
1706
|
resolvable: false,
|
|
1666
1707
|
message: 'Table "{table}" is read but never written.',
|
|
1667
1708
|
docs: 'cross-domain/read-never-written',
|
|
@@ -1679,7 +1720,6 @@ export const RULE_REGISTRY = {
|
|
|
1679
1720
|
analyzer: 'cross-domain',
|
|
1680
1721
|
field: 'rule',
|
|
1681
1722
|
input: ['schema_usage', 'functions'],
|
|
1682
|
-
gating: false,
|
|
1683
1723
|
resolvable: false,
|
|
1684
1724
|
message: 'Transaction boundary spans {count} tables.',
|
|
1685
1725
|
docs: 'cross-domain/transaction-boundary',
|
|
@@ -1697,7 +1737,6 @@ export const RULE_REGISTRY = {
|
|
|
1697
1737
|
analyzer: 'cross-domain',
|
|
1698
1738
|
field: 'rule',
|
|
1699
1739
|
input: ['schema_usage', 'functions'],
|
|
1700
|
-
gating: false,
|
|
1701
1740
|
resolvable: false,
|
|
1702
1741
|
message: 'Validation bypass: {detail}.',
|
|
1703
1742
|
docs: 'cross-domain/validation-bypass',
|
|
@@ -1715,7 +1754,6 @@ export const RULE_REGISTRY = {
|
|
|
1715
1754
|
analyzer: 'cross-domain',
|
|
1716
1755
|
field: 'rule',
|
|
1717
1756
|
input: ['schema_usage', 'functions'],
|
|
1718
|
-
gating: false,
|
|
1719
1757
|
resolvable: false,
|
|
1720
1758
|
message: 'Uncovered risk: {detail}.',
|
|
1721
1759
|
docs: 'cross-domain/uncovered-risk',
|
|
@@ -1765,11 +1803,13 @@ export const MCP_DEFAULT_ANALYZERS = [
|
|
|
1765
1803
|
* The registry records which field on the Violation carries the rule ID
|
|
1766
1804
|
* (`field` — `rule` for almost every analyzer, `type` for dependency-graph).
|
|
1767
1805
|
* This helper reads that field off the violation and matches it against the
|
|
1768
|
-
* registry key, so gate
|
|
1806
|
+
* registry key, so the gate's resolution-gap detection (Spec 45 R1) never
|
|
1807
|
+
* hard-codes a field.
|
|
1769
1808
|
*
|
|
1770
1809
|
* Invariant violations (user-defined rule IDs) have no registry entry and
|
|
1771
|
-
* return `undefined
|
|
1772
|
-
*
|
|
1810
|
+
* return `undefined`. They still gate (Spec 45 R1) — the gate blocks on every
|
|
1811
|
+
* finding at a blocking severity; the registry only determines whether a
|
|
1812
|
+
* missing resolution is a recorded gap.
|
|
1773
1813
|
*/
|
|
1774
1814
|
export function getViolationRuleEntry(v) {
|
|
1775
1815
|
if (!v.analyzer)
|