slopbrick 0.18.7 → 0.19.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/dist/engine/worker.cjs +2964 -933
- package/dist/engine/worker.js +2957 -935
- package/dist/index.cjs +3201 -1048
- package/dist/index.d.cts +86 -0
- package/dist/index.d.ts +86 -0
- package/dist/index.js +3205 -1052
- package/package.json +5 -3
package/dist/index.cjs
CHANGED
|
@@ -36,7 +36,7 @@ var VERSION;
|
|
|
36
36
|
var init_header = __esm({
|
|
37
37
|
"src/types/_header.ts"() {
|
|
38
38
|
"use strict";
|
|
39
|
-
VERSION = "0.
|
|
39
|
+
VERSION = "0.19.0";
|
|
40
40
|
}
|
|
41
41
|
});
|
|
42
42
|
|
|
@@ -28238,6 +28238,20 @@ var init_unreachable = __esm({
|
|
|
28238
28238
|
});
|
|
28239
28239
|
|
|
28240
28240
|
// src/rules/dead/unused-import.ts
|
|
28241
|
+
function collectRustReferencedNames(source) {
|
|
28242
|
+
const out = /* @__PURE__ */ new Set();
|
|
28243
|
+
for (const m of source.matchAll(/\b([A-Za-z_][A-Za-z0-9_]*)\b/g)) {
|
|
28244
|
+
out.add(m[1]);
|
|
28245
|
+
}
|
|
28246
|
+
return out;
|
|
28247
|
+
}
|
|
28248
|
+
function stripUseDeclarations(source) {
|
|
28249
|
+
let out = source;
|
|
28250
|
+
out = out.replace(/^\s*use\s+[\s\S]*?;\s*$/gm, "");
|
|
28251
|
+
out = out.replace(/\/\/[^\n]*/g, "");
|
|
28252
|
+
out = out.replace(/\/\*[\s\S]*?\*\//g, "");
|
|
28253
|
+
return out;
|
|
28254
|
+
}
|
|
28241
28255
|
var unusedImportRule;
|
|
28242
28256
|
var init_unused_import = __esm({
|
|
28243
28257
|
"src/rules/dead/unused-import.ts"() {
|
|
@@ -28273,6 +28287,26 @@ var init_unused_import = __esm({
|
|
|
28273
28287
|
advice: `Remove the import or use '${binding.name}' somewhere in the file. This is the most common AI-iteration rot \u2014 the model added the import when it introduced a feature, then rewrote the function without cleaning up.`
|
|
28274
28288
|
});
|
|
28275
28289
|
}
|
|
28290
|
+
if (facts.v2.rustFile) {
|
|
28291
|
+
const strippedSource = stripUseDeclarations(facts.v2._source ?? "");
|
|
28292
|
+
const referenced = collectRustReferencedNames(strippedSource);
|
|
28293
|
+
for (const imp of facts.v2.rustFile.imports) {
|
|
28294
|
+
for (const nameEntry of imp.names) {
|
|
28295
|
+
if (referenced.has(nameEntry.name)) continue;
|
|
28296
|
+
const source = ` from '${imp.path}'`;
|
|
28297
|
+
issues.push({
|
|
28298
|
+
ruleId: "dead/unused-import",
|
|
28299
|
+
category: "logic",
|
|
28300
|
+
severity: "low",
|
|
28301
|
+
aiSpecific: true,
|
|
28302
|
+
message: `Unused import: '${nameEntry.name}'${source}`,
|
|
28303
|
+
line: imp.line,
|
|
28304
|
+
column: imp.column,
|
|
28305
|
+
advice: `Remove the '${imp.path}' import or use '${nameEntry.name}' somewhere in the file. Rust's compiler only flags unused imports per module \u2014 the tree-sitter-backed walker here surfaces them for slopbrick's dead-code rules regardless of #[allow(unused_imports)].`
|
|
28306
|
+
});
|
|
28307
|
+
}
|
|
28308
|
+
}
|
|
28309
|
+
}
|
|
28276
28310
|
return issues;
|
|
28277
28311
|
}
|
|
28278
28312
|
});
|
|
@@ -29015,10 +29049,67 @@ var init_dart = __esm({
|
|
|
29015
29049
|
}
|
|
29016
29050
|
});
|
|
29017
29051
|
|
|
29052
|
+
// src/engine/parser-rust.ts
|
|
29053
|
+
function getRustParser() {
|
|
29054
|
+
if (cachedParser) return { ok: true, parser: cachedParser };
|
|
29055
|
+
if (loadError) return { ok: false, error: loadError };
|
|
29056
|
+
try {
|
|
29057
|
+
rustLanguage = import_tree_sitter_rust.default;
|
|
29058
|
+
if (!rustLanguage || typeof rustLanguage !== "object") {
|
|
29059
|
+
throw new Error("tree-sitter-rust: language export is missing or malformed");
|
|
29060
|
+
}
|
|
29061
|
+
const parser = new import_tree_sitter.default();
|
|
29062
|
+
parser.setLanguage(rustLanguage);
|
|
29063
|
+
cachedParser = parser;
|
|
29064
|
+
return { ok: true, parser };
|
|
29065
|
+
} catch (err) {
|
|
29066
|
+
loadError = err instanceof Error ? err : new Error(String(err));
|
|
29067
|
+
return { ok: false, error: loadError };
|
|
29068
|
+
}
|
|
29069
|
+
}
|
|
29070
|
+
function effectiveParser() {
|
|
29071
|
+
if (forcedFailure) return { ok: false, error: forcedFailure };
|
|
29072
|
+
return getRustParser();
|
|
29073
|
+
}
|
|
29074
|
+
function parseRust(source) {
|
|
29075
|
+
const result = effectiveParser();
|
|
29076
|
+
if (!result.ok) return null;
|
|
29077
|
+
if (!source || source.trim() === "") return null;
|
|
29078
|
+
try {
|
|
29079
|
+
const rawTree = result.parser.parse(source);
|
|
29080
|
+
if (!rawTree) return null;
|
|
29081
|
+
const tree = rawTree;
|
|
29082
|
+
if (!tree || !tree.rootNode) return null;
|
|
29083
|
+
if (tree.rootNode.type === "ERROR" && tree.rootNode.childCount === 0) {
|
|
29084
|
+
return null;
|
|
29085
|
+
}
|
|
29086
|
+
return tree;
|
|
29087
|
+
} catch {
|
|
29088
|
+
return null;
|
|
29089
|
+
}
|
|
29090
|
+
}
|
|
29091
|
+
function isRustParserAvailable() {
|
|
29092
|
+
const result = getRustParser();
|
|
29093
|
+
return result.ok;
|
|
29094
|
+
}
|
|
29095
|
+
var import_tree_sitter, import_tree_sitter_rust, cachedParser, rustLanguage, loadError, forcedFailure;
|
|
29096
|
+
var init_parser_rust = __esm({
|
|
29097
|
+
"src/engine/parser-rust.ts"() {
|
|
29098
|
+
"use strict";
|
|
29099
|
+
import_tree_sitter = __toESM(require("tree-sitter"), 1);
|
|
29100
|
+
import_tree_sitter_rust = __toESM(require("tree-sitter-rust"), 1);
|
|
29101
|
+
cachedParser = null;
|
|
29102
|
+
rustLanguage = null;
|
|
29103
|
+
loadError = null;
|
|
29104
|
+
forcedFailure = null;
|
|
29105
|
+
}
|
|
29106
|
+
});
|
|
29107
|
+
|
|
29018
29108
|
// src/engine/visitors/rust.ts
|
|
29019
29109
|
var rust_exports = {};
|
|
29020
29110
|
__export(rust_exports, {
|
|
29021
|
-
extractRustPatterns: () => extractRustPatterns
|
|
29111
|
+
extractRustPatterns: () => extractRustPatterns,
|
|
29112
|
+
parseRustFile: () => parseRustFile
|
|
29022
29113
|
});
|
|
29023
29114
|
function extractRustPatterns(filePath, source) {
|
|
29024
29115
|
const service = [];
|
|
@@ -29071,188 +29162,487 @@ function extractRustPatterns(filePath, source) {
|
|
|
29071
29162
|
}
|
|
29072
29163
|
return { service, route, ormModel };
|
|
29073
29164
|
}
|
|
29074
|
-
|
|
29075
|
-
|
|
29076
|
-
|
|
29077
|
-
|
|
29078
|
-
|
|
29079
|
-
|
|
29080
|
-
|
|
29081
|
-
|
|
29082
|
-
|
|
29083
|
-
|
|
29084
|
-
"Helper",
|
|
29085
|
-
"Factory",
|
|
29086
|
-
"Provider",
|
|
29087
|
-
"Store",
|
|
29088
|
-
"API",
|
|
29089
|
-
"Client",
|
|
29090
|
-
"Adapter",
|
|
29091
|
-
"Resolver",
|
|
29092
|
-
"Mapper",
|
|
29093
|
-
"Transformer",
|
|
29094
|
-
"Serializer",
|
|
29095
|
-
"Validator",
|
|
29096
|
-
"Strategy",
|
|
29097
|
-
"Facade",
|
|
29098
|
-
"Decorator",
|
|
29099
|
-
"Observer",
|
|
29100
|
-
"Builder",
|
|
29101
|
-
"Command",
|
|
29102
|
-
"Processor",
|
|
29103
|
-
"Worker",
|
|
29104
|
-
"Job",
|
|
29105
|
-
"Actor",
|
|
29106
|
-
"Executor"
|
|
29107
|
-
];
|
|
29108
|
-
SERVICE_SUFFIX_GROUP4 = `(?:${SERVICE_SUFFIXES4.join("|")})`;
|
|
29109
|
-
RUST_SERVICE_STRUCT_RE = new RegExp(
|
|
29110
|
-
`^(?:pub(?:\\(crate\\)|\\(super\\))?\\s+)?struct\\s+(\\w+?)${SERVICE_SUFFIX_GROUP4}?\\b`,
|
|
29111
|
-
"gm"
|
|
29112
|
-
);
|
|
29113
|
-
RUST_SERVICE_IMPL_RE = new RegExp(
|
|
29114
|
-
`^impl(?:<[^>]+>)?\\s+(?:${SERVICE_SUFFIX_GROUP4}\\s+for\\s+)?(\\w+?)${SERVICE_SUFFIX_GROUP4}?\\b`,
|
|
29115
|
-
"gm"
|
|
29116
|
-
);
|
|
29117
|
-
RUST_ACTIX_ROUTE_RE = /#\[(?:get|post|put|delete|patch|head|route)\(\s*"(\/[^"]+)"\s*[\),]/g;
|
|
29118
|
-
RUST_AXUM_ROUTE_RE = /\.route\(\s*"(\/[^"]+)"\s*,\s*(?:get|post|put|delete|patch)/g;
|
|
29119
|
-
RUST_DIESEL_RE = /#\[derive\([^\]]*Queryable[^\]]*\)\][\s\S]{0,200}?struct\s+(\w+)/g;
|
|
29120
|
-
RUST_SEAORM_RE = /#\[derive\([^\]]*DeriveEntityModel[^\]]*\)\][\s\S]{0,200}?struct\s+(\w+)/g;
|
|
29121
|
-
RUST_SQLX_RE = /#\[derive\([^\]]*sqlx::FromRow[^\]]*\)\][\s\S]{0,200}?struct\s+(\w+)/g;
|
|
29165
|
+
function parseRustFile(filePath, source, options = {}) {
|
|
29166
|
+
const empty = {
|
|
29167
|
+
imports: [],
|
|
29168
|
+
functions: [],
|
|
29169
|
+
structs: [],
|
|
29170
|
+
traits: [],
|
|
29171
|
+
impls: []
|
|
29172
|
+
};
|
|
29173
|
+
if (!isRustParserAvailable() || options.forceFallback) {
|
|
29174
|
+
return empty;
|
|
29122
29175
|
}
|
|
29123
|
-
|
|
29124
|
-
|
|
29125
|
-
|
|
29126
|
-
|
|
29127
|
-
|
|
29128
|
-
|
|
29129
|
-
|
|
29130
|
-
|
|
29131
|
-
|
|
29132
|
-
|
|
29133
|
-
|
|
29134
|
-
|
|
29135
|
-
|
|
29136
|
-
|
|
29137
|
-
|
|
29138
|
-
|
|
29139
|
-
|
|
29176
|
+
const tree = parseRust(source);
|
|
29177
|
+
if (!tree) return empty;
|
|
29178
|
+
return walkRustTree(tree);
|
|
29179
|
+
}
|
|
29180
|
+
function walkRustTree(tree) {
|
|
29181
|
+
const ctx = { inTestConfig: false };
|
|
29182
|
+
const out = {
|
|
29183
|
+
imports: [],
|
|
29184
|
+
functions: [],
|
|
29185
|
+
structs: [],
|
|
29186
|
+
traits: [],
|
|
29187
|
+
impls: []
|
|
29188
|
+
};
|
|
29189
|
+
walkChildren(tree.rootNode, ctx, out);
|
|
29190
|
+
return out;
|
|
29191
|
+
}
|
|
29192
|
+
function walkChildren(node, ctx, out) {
|
|
29193
|
+
for (let i = 0; i < node.namedChildCount; i++) {
|
|
29194
|
+
const child = node.namedChild(i);
|
|
29195
|
+
if (!child) continue;
|
|
29196
|
+
visitNode(child, ctx, out);
|
|
29140
29197
|
}
|
|
29141
|
-
|
|
29142
|
-
|
|
29143
|
-
|
|
29144
|
-
|
|
29145
|
-
|
|
29146
|
-
|
|
29198
|
+
}
|
|
29199
|
+
function visitNode(node, ctx, out) {
|
|
29200
|
+
const innerCtx = { ...ctx };
|
|
29201
|
+
const attrState = readPrecedingAttributes(node);
|
|
29202
|
+
switch (node.type) {
|
|
29203
|
+
case "use_declaration": {
|
|
29204
|
+
out.imports.push(extractUse(node));
|
|
29205
|
+
return;
|
|
29206
|
+
}
|
|
29207
|
+
case "function_item": {
|
|
29208
|
+
const isMethod = isInImplBlock(node);
|
|
29209
|
+
out.functions.push(extractFunction(node, attrState, innerCtx.inTestConfig, isMethod));
|
|
29210
|
+
walkChildren(getField(node, "body") ?? node, innerCtx, out);
|
|
29211
|
+
return;
|
|
29212
|
+
}
|
|
29213
|
+
case "struct_item": {
|
|
29214
|
+
out.structs.push(extractStruct(node, attrState));
|
|
29215
|
+
const body = getField(node, "body");
|
|
29216
|
+
if (body) walkChildren(body, innerCtx, out);
|
|
29217
|
+
return;
|
|
29218
|
+
}
|
|
29219
|
+
case "trait_item": {
|
|
29220
|
+
out.traits.push(extractTrait(node, attrState));
|
|
29221
|
+
const body = getField(node, "body");
|
|
29222
|
+
if (body) walkChildren(body, innerCtx, out);
|
|
29223
|
+
return;
|
|
29224
|
+
}
|
|
29225
|
+
case "impl_item": {
|
|
29226
|
+
const implEntry = extractImpl(node, attrState, innerCtx);
|
|
29227
|
+
out.impls.push(implEntry.entry);
|
|
29228
|
+
const body = getField(node, "body");
|
|
29229
|
+
if (body) walkChildren(body, innerCtx, out);
|
|
29230
|
+
return;
|
|
29231
|
+
}
|
|
29232
|
+
case "mod_item": {
|
|
29233
|
+
const modIsTest = innerCtx.inTestConfig || attrState.isTestCfg;
|
|
29234
|
+
const modCtx = { ...innerCtx, inTestConfig: modIsTest };
|
|
29235
|
+
const body = getField(node, "body");
|
|
29236
|
+
if (body) walkChildren(body, modCtx, out);
|
|
29237
|
+
return;
|
|
29238
|
+
}
|
|
29239
|
+
default: {
|
|
29240
|
+
for (let i = 0; i < node.namedChildCount; i++) {
|
|
29241
|
+
const child = node.namedChild(i);
|
|
29242
|
+
if (child) visitNode(child, innerCtx, out);
|
|
29243
|
+
}
|
|
29244
|
+
}
|
|
29147
29245
|
}
|
|
29148
|
-
|
|
29149
|
-
|
|
29246
|
+
}
|
|
29247
|
+
function readPrecedingAttributes(node) {
|
|
29248
|
+
const state = {
|
|
29249
|
+
isTestCfg: false,
|
|
29250
|
+
isTest: false,
|
|
29251
|
+
isPub: false,
|
|
29252
|
+
derives: []
|
|
29253
|
+
};
|
|
29254
|
+
const parent = node.parent;
|
|
29255
|
+
if (!parent) return state;
|
|
29256
|
+
for (let i = 0; i < parent.namedChildCount; i++) {
|
|
29257
|
+
const sibling = parent.namedChild(i);
|
|
29258
|
+
if (!sibling || sibling === node) continue;
|
|
29259
|
+
if (sibling.endIndex > node.startIndex) continue;
|
|
29260
|
+
if (sibling.type !== "attribute_item") continue;
|
|
29261
|
+
decodeAttribute(sibling, state);
|
|
29262
|
+
}
|
|
29263
|
+
return state;
|
|
29264
|
+
}
|
|
29265
|
+
function decodeAttribute(attr, state) {
|
|
29266
|
+
for (let i = 0; i < attr.namedChildCount; i++) {
|
|
29267
|
+
const child = attr.namedChild(i);
|
|
29268
|
+
if (!child || child.type !== "attribute") continue;
|
|
29269
|
+
const name = firstIdentifier(child);
|
|
29150
29270
|
if (!name) continue;
|
|
29151
|
-
if (
|
|
29152
|
-
|
|
29153
|
-
|
|
29154
|
-
|
|
29155
|
-
|
|
29156
|
-
|
|
29157
|
-
|
|
29158
|
-
|
|
29159
|
-
|
|
29271
|
+
if (name === "cfg") {
|
|
29272
|
+
const cfgText = child.text;
|
|
29273
|
+
if (/\btest\b/.test(cfgText) && !/\bnot\(test\)/.test(cfgText)) {
|
|
29274
|
+
state.isTestCfg = true;
|
|
29275
|
+
}
|
|
29276
|
+
} else if (name === "test") {
|
|
29277
|
+
state.isTest = true;
|
|
29278
|
+
} else if (name === "derive") {
|
|
29279
|
+
for (let j = 0; j < child.namedChildCount; j++) {
|
|
29280
|
+
const inner = child.namedChild(j);
|
|
29281
|
+
if (inner) {
|
|
29282
|
+
const matches = inner.text.matchAll(/\b([A-Z][A-Za-z0-9_]*)\b/g);
|
|
29283
|
+
for (const m of matches) state.derives.push(m[1]);
|
|
29284
|
+
}
|
|
29285
|
+
}
|
|
29286
|
+
}
|
|
29160
29287
|
}
|
|
29161
|
-
return { service, route, ormModel };
|
|
29162
29288
|
}
|
|
29163
|
-
|
|
29164
|
-
|
|
29165
|
-
|
|
29166
|
-
|
|
29167
|
-
|
|
29168
|
-
|
|
29169
|
-
|
|
29170
|
-
|
|
29171
|
-
|
|
29172
|
-
|
|
29173
|
-
|
|
29174
|
-
|
|
29175
|
-
|
|
29176
|
-
|
|
29177
|
-
|
|
29178
|
-
|
|
29179
|
-
"
|
|
29180
|
-
|
|
29181
|
-
"
|
|
29182
|
-
|
|
29183
|
-
"
|
|
29184
|
-
|
|
29185
|
-
|
|
29186
|
-
|
|
29187
|
-
|
|
29188
|
-
|
|
29189
|
-
|
|
29190
|
-
|
|
29191
|
-
"
|
|
29192
|
-
|
|
29193
|
-
|
|
29194
|
-
|
|
29195
|
-
|
|
29196
|
-
|
|
29197
|
-
|
|
29198
|
-
|
|
29199
|
-
|
|
29200
|
-
|
|
29201
|
-
|
|
29202
|
-
|
|
29289
|
+
function firstIdentifier(node) {
|
|
29290
|
+
const text = node.text;
|
|
29291
|
+
const idMatch = text.match(/^([a-zA-Z_][a-zA-Z0-9_]*)/);
|
|
29292
|
+
return idMatch ? idMatch[1] : null;
|
|
29293
|
+
}
|
|
29294
|
+
function extractUse(node) {
|
|
29295
|
+
const text = node.text;
|
|
29296
|
+
const argument = node.namedChild(0);
|
|
29297
|
+
const argField = node.childForFieldName("argument");
|
|
29298
|
+
const path = argField?.text ?? argument?.text ?? "";
|
|
29299
|
+
const names = [];
|
|
29300
|
+
let isGlob = false;
|
|
29301
|
+
const useListNode = findUseListNode(argument);
|
|
29302
|
+
if (useListNode) {
|
|
29303
|
+
for (let i = 0; i < useListNode.namedChildCount; i++) {
|
|
29304
|
+
const item = useListNode.namedChild(i);
|
|
29305
|
+
if (item.type === "use_wildcard") {
|
|
29306
|
+
isGlob = true;
|
|
29307
|
+
} else if (item.type === "identifier") {
|
|
29308
|
+
names.push({ name: item.text });
|
|
29309
|
+
} else if (item.type === "use_as_clause") {
|
|
29310
|
+
const alias = item.childForFieldName("alias");
|
|
29311
|
+
const binding = item.childForFieldName("path");
|
|
29312
|
+
if (binding) {
|
|
29313
|
+
names.push({ name: binding.text, alias: alias?.text });
|
|
29314
|
+
} else {
|
|
29315
|
+
names.push({ name: item.text });
|
|
29316
|
+
}
|
|
29317
|
+
} else if (item.type === "scoped_identifier") {
|
|
29318
|
+
const idents = collectIdentifiers(item);
|
|
29319
|
+
names.push({ name: idents[idents.length - 1] ?? item.text });
|
|
29320
|
+
} else if (item.text.includes(" as ")) {
|
|
29321
|
+
const [head, alias] = item.text.split(/\s+as\s+/);
|
|
29322
|
+
names.push({ name: (head ?? "").trim(), alias: alias?.trim() });
|
|
29323
|
+
} else {
|
|
29324
|
+
names.push({ name: item.text });
|
|
29325
|
+
}
|
|
29326
|
+
}
|
|
29327
|
+
} else if (argument?.type === "use_wildcard") {
|
|
29328
|
+
isGlob = true;
|
|
29329
|
+
} else if (argument) {
|
|
29330
|
+
const idents = collectIdentifiers(argument);
|
|
29331
|
+
const last = idents[idents.length - 1] ?? argument.text;
|
|
29332
|
+
names.push({ name: last });
|
|
29333
|
+
const asMatch = text.match(/\s+as\s+(\w+)\s*;?\s*$/);
|
|
29334
|
+
if (asMatch) names[0].alias = asMatch[1];
|
|
29203
29335
|
}
|
|
29204
|
-
|
|
29205
|
-
|
|
29206
|
-
|
|
29207
|
-
|
|
29208
|
-
|
|
29209
|
-
|
|
29210
|
-
}
|
|
29211
|
-
|
|
29212
|
-
|
|
29213
|
-
const
|
|
29214
|
-
const
|
|
29215
|
-
const
|
|
29216
|
-
|
|
29217
|
-
|
|
29218
|
-
|
|
29219
|
-
|
|
29220
|
-
|
|
29336
|
+
return {
|
|
29337
|
+
path: path.trim(),
|
|
29338
|
+
names,
|
|
29339
|
+
isGlob,
|
|
29340
|
+
line: node.startPosition.row + 1,
|
|
29341
|
+
column: node.startPosition.column
|
|
29342
|
+
};
|
|
29343
|
+
}
|
|
29344
|
+
function extractFunction(node, attrs, inheritedTestConfig, isMethod) {
|
|
29345
|
+
const nameNode = node.childForFieldName("name");
|
|
29346
|
+
const name = nameNode?.text ?? "<anon>";
|
|
29347
|
+
const params = node.childForFieldName("parameters");
|
|
29348
|
+
const body = node.childForFieldName("body");
|
|
29349
|
+
const visibilityMod = node.namedChild(0);
|
|
29350
|
+
const isPublic = visibilityMod?.type === "visibility_modifier";
|
|
29351
|
+
let receiver;
|
|
29352
|
+
if (isMethod && params) {
|
|
29353
|
+
const selfParam = findSelfParameter(params);
|
|
29354
|
+
if (selfParam) receiver = selfParam.text;
|
|
29355
|
+
}
|
|
29356
|
+
const bodyLines = body ? body.endPosition.row - body.startPosition.row + 1 : 0;
|
|
29357
|
+
const inTestConfig = inheritedTestConfig || attrs.isTest || attrs.isTestCfg || isFunctionAttrTest(node);
|
|
29358
|
+
return {
|
|
29359
|
+
name,
|
|
29360
|
+
line: node.startPosition.row + 1,
|
|
29361
|
+
column: node.startPosition.column,
|
|
29362
|
+
isPublic,
|
|
29363
|
+
isMethod,
|
|
29364
|
+
receiver,
|
|
29365
|
+
bodyLines,
|
|
29366
|
+
inTestConfig
|
|
29367
|
+
};
|
|
29368
|
+
}
|
|
29369
|
+
function extractStruct(node, attrs) {
|
|
29370
|
+
const nameNode = node.childForFieldName("name");
|
|
29371
|
+
return {
|
|
29372
|
+
name: nameNode?.text ?? "<anon>",
|
|
29373
|
+
line: node.startPosition.row + 1,
|
|
29374
|
+
column: node.startPosition.column,
|
|
29375
|
+
isPublic: hasVisibility(node),
|
|
29376
|
+
isDerive: attrs.derives.length > 0,
|
|
29377
|
+
derives: [...attrs.derives]
|
|
29378
|
+
};
|
|
29379
|
+
}
|
|
29380
|
+
function extractTrait(node, _attrs) {
|
|
29381
|
+
const nameNode = node.childForFieldName("name");
|
|
29382
|
+
return {
|
|
29383
|
+
name: nameNode?.text ?? "<anon>",
|
|
29384
|
+
line: node.startPosition.row + 1,
|
|
29385
|
+
column: node.startPosition.column,
|
|
29386
|
+
isPublic: hasVisibility(node)
|
|
29387
|
+
};
|
|
29388
|
+
}
|
|
29389
|
+
function extractImpl(node, _attrs, _ctx) {
|
|
29390
|
+
const traitNode = node.childForFieldName("trait");
|
|
29391
|
+
const typeNode = node.childForFieldName("type");
|
|
29392
|
+
const typeText = typeNode?.text ?? "<anon>";
|
|
29393
|
+
const traitText = traitNode?.text;
|
|
29394
|
+
const body = node.childForFieldName("body");
|
|
29395
|
+
const methods = [];
|
|
29396
|
+
if (body) {
|
|
29397
|
+
for (let i = 0; i < body.namedChildCount; i++) {
|
|
29398
|
+
const child = body.namedChild(i);
|
|
29399
|
+
if (child?.type === "function_item") {
|
|
29400
|
+
const m = child.childForFieldName("name");
|
|
29401
|
+
if (m) methods.push(m.text);
|
|
29402
|
+
}
|
|
29403
|
+
}
|
|
29221
29404
|
}
|
|
29222
|
-
|
|
29223
|
-
|
|
29224
|
-
|
|
29225
|
-
|
|
29226
|
-
|
|
29227
|
-
|
|
29405
|
+
return {
|
|
29406
|
+
entry: {
|
|
29407
|
+
type: typeText,
|
|
29408
|
+
trait: traitText ?? void 0,
|
|
29409
|
+
methods,
|
|
29410
|
+
line: node.startPosition.row + 1,
|
|
29411
|
+
column: node.startPosition.column
|
|
29412
|
+
}
|
|
29413
|
+
};
|
|
29414
|
+
}
|
|
29415
|
+
function findUseListNode(argument) {
|
|
29416
|
+
if (!argument) return null;
|
|
29417
|
+
if (argument.type === "use_list") return argument;
|
|
29418
|
+
if (argument.type === "scoped_use_list") {
|
|
29419
|
+
for (let i = 0; i < argument.namedChildCount; i++) {
|
|
29420
|
+
const c = argument.namedChild(i);
|
|
29421
|
+
if (c?.type === "use_list") return c;
|
|
29422
|
+
}
|
|
29228
29423
|
}
|
|
29229
|
-
|
|
29230
|
-
|
|
29231
|
-
|
|
29232
|
-
|
|
29233
|
-
|
|
29234
|
-
|
|
29424
|
+
return null;
|
|
29425
|
+
}
|
|
29426
|
+
function getField(node, fieldName) {
|
|
29427
|
+
return node.childForFieldName(fieldName);
|
|
29428
|
+
}
|
|
29429
|
+
function collectIdentifiers(node) {
|
|
29430
|
+
const out = [];
|
|
29431
|
+
for (let i = 0; i < node.namedChildCount; i++) {
|
|
29432
|
+
const child = node.namedChild(i);
|
|
29433
|
+
if (!child) continue;
|
|
29434
|
+
if (child.type === "identifier" || child.type === "type_identifier") {
|
|
29435
|
+
out.push(child.text);
|
|
29436
|
+
} else if (child.type === "scoped_identifier" || child.type === "nested_identifier") {
|
|
29437
|
+
out.push(...collectIdentifiers(child));
|
|
29438
|
+
}
|
|
29235
29439
|
}
|
|
29236
|
-
|
|
29237
|
-
|
|
29238
|
-
|
|
29239
|
-
|
|
29240
|
-
|
|
29241
|
-
|
|
29440
|
+
return out;
|
|
29441
|
+
}
|
|
29442
|
+
function hasVisibility(node) {
|
|
29443
|
+
return node.namedChild(0)?.type === "visibility_modifier";
|
|
29444
|
+
}
|
|
29445
|
+
function isInImplBlock(node) {
|
|
29446
|
+
for (let p = node.parent; p; p = p.parent) {
|
|
29447
|
+
if (p.type === "impl_item") return true;
|
|
29448
|
+
if (p.type === "function_item" || p.type === "source_file") return false;
|
|
29242
29449
|
}
|
|
29243
|
-
|
|
29244
|
-
|
|
29245
|
-
|
|
29246
|
-
|
|
29247
|
-
|
|
29450
|
+
return false;
|
|
29451
|
+
}
|
|
29452
|
+
function findSelfParameter(params) {
|
|
29453
|
+
for (let i = 0; i < params.namedChildCount; i++) {
|
|
29454
|
+
const child = params.namedChild(i);
|
|
29455
|
+
if (child?.type === "self_parameter") return child;
|
|
29248
29456
|
}
|
|
29249
|
-
return
|
|
29457
|
+
return null;
|
|
29250
29458
|
}
|
|
29251
|
-
|
|
29252
|
-
|
|
29253
|
-
|
|
29459
|
+
function isFunctionAttrTest(node) {
|
|
29460
|
+
void node;
|
|
29461
|
+
return false;
|
|
29462
|
+
}
|
|
29463
|
+
var SERVICE_SUFFIXES4, SERVICE_SUFFIX_GROUP4, RUST_SERVICE_STRUCT_RE, RUST_SERVICE_IMPL_RE, RUST_ACTIX_ROUTE_RE, RUST_AXUM_ROUTE_RE, RUST_DIESEL_RE, RUST_SEAORM_RE, RUST_SQLX_RE;
|
|
29464
|
+
var init_rust = __esm({
|
|
29465
|
+
"src/engine/visitors/rust.ts"() {
|
|
29254
29466
|
"use strict";
|
|
29255
|
-
|
|
29467
|
+
init_parser_rust();
|
|
29468
|
+
SERVICE_SUFFIXES4 = [
|
|
29469
|
+
"Service",
|
|
29470
|
+
"Manager",
|
|
29471
|
+
"Handler",
|
|
29472
|
+
"Repository",
|
|
29473
|
+
"Controller",
|
|
29474
|
+
"Helper",
|
|
29475
|
+
"Factory",
|
|
29476
|
+
"Provider",
|
|
29477
|
+
"Store",
|
|
29478
|
+
"API",
|
|
29479
|
+
"Client",
|
|
29480
|
+
"Adapter",
|
|
29481
|
+
"Resolver",
|
|
29482
|
+
"Mapper",
|
|
29483
|
+
"Transformer",
|
|
29484
|
+
"Serializer",
|
|
29485
|
+
"Validator",
|
|
29486
|
+
"Strategy",
|
|
29487
|
+
"Facade",
|
|
29488
|
+
"Decorator",
|
|
29489
|
+
"Observer",
|
|
29490
|
+
"Builder",
|
|
29491
|
+
"Command",
|
|
29492
|
+
"Processor",
|
|
29493
|
+
"Worker",
|
|
29494
|
+
"Job",
|
|
29495
|
+
"Actor",
|
|
29496
|
+
"Executor"
|
|
29497
|
+
];
|
|
29498
|
+
SERVICE_SUFFIX_GROUP4 = `(?:${SERVICE_SUFFIXES4.join("|")})`;
|
|
29499
|
+
RUST_SERVICE_STRUCT_RE = new RegExp(
|
|
29500
|
+
`^(?:pub(?:\\(crate\\)|\\(super\\))?\\s+)?struct\\s+(\\w+?)${SERVICE_SUFFIX_GROUP4}?\\b`,
|
|
29501
|
+
"gm"
|
|
29502
|
+
);
|
|
29503
|
+
RUST_SERVICE_IMPL_RE = new RegExp(
|
|
29504
|
+
`^impl(?:<[^>]+>)?\\s+(?:${SERVICE_SUFFIX_GROUP4}\\s+for\\s+)?(\\w+?)${SERVICE_SUFFIX_GROUP4}?\\b`,
|
|
29505
|
+
"gm"
|
|
29506
|
+
);
|
|
29507
|
+
RUST_ACTIX_ROUTE_RE = /#\[(?:get|post|put|delete|patch|head|route)\(\s*"(\/[^"]+)"\s*[\),]/g;
|
|
29508
|
+
RUST_AXUM_ROUTE_RE = /\.route\(\s*"(\/[^"]+)"\s*,\s*(?:get|post|put|delete|patch)/g;
|
|
29509
|
+
RUST_DIESEL_RE = /#\[derive\([^\]]*Queryable[^\]]*\)\][\s\S]{0,200}?struct\s+(\w+)/g;
|
|
29510
|
+
RUST_SEAORM_RE = /#\[derive\([^\]]*DeriveEntityModel[^\]]*\)\][\s\S]{0,200}?struct\s+(\w+)/g;
|
|
29511
|
+
RUST_SQLX_RE = /#\[derive\([^\]]*sqlx::FromRow[^\]]*\)\][\s\S]{0,200}?struct\s+(\w+)/g;
|
|
29512
|
+
}
|
|
29513
|
+
});
|
|
29514
|
+
|
|
29515
|
+
// src/engine/visitors/cpp.ts
|
|
29516
|
+
var cpp_exports = {};
|
|
29517
|
+
__export(cpp_exports, {
|
|
29518
|
+
extractCppPatterns: () => extractCppPatterns
|
|
29519
|
+
});
|
|
29520
|
+
function extractCppPatterns(filePath, source) {
|
|
29521
|
+
const service = [];
|
|
29522
|
+
const route = [];
|
|
29523
|
+
const ormModel = [];
|
|
29524
|
+
const seenService = /* @__PURE__ */ new Set();
|
|
29525
|
+
for (const m of source.matchAll(CPP_SERVICE_RE)) {
|
|
29526
|
+
const name = m[1];
|
|
29527
|
+
if (seenService.has(name)) continue;
|
|
29528
|
+
seenService.add(name);
|
|
29529
|
+
service.push({ name, files: [filePath], imports: [] });
|
|
29530
|
+
}
|
|
29531
|
+
const seenRoute = /* @__PURE__ */ new Set();
|
|
29532
|
+
for (const m of source.matchAll(CPP_CROW_ROUTE_RE)) {
|
|
29533
|
+
const name = m[1];
|
|
29534
|
+
if (seenRoute.has(name)) continue;
|
|
29535
|
+
seenRoute.add(name);
|
|
29536
|
+
route.push({ name, files: [filePath], imports: [] });
|
|
29537
|
+
}
|
|
29538
|
+
for (const m of source.matchAll(CPP_DROGON_ROUTE_RE)) {
|
|
29539
|
+
const name = m[1] || m[2];
|
|
29540
|
+
if (!name) continue;
|
|
29541
|
+
if (seenRoute.has(name)) continue;
|
|
29542
|
+
seenRoute.add(name);
|
|
29543
|
+
route.push({ name, files: [filePath], imports: [] });
|
|
29544
|
+
}
|
|
29545
|
+
for (const m of source.matchAll(CPP_PISTACHE_ROUTE_RE)) {
|
|
29546
|
+
const name = m[1];
|
|
29547
|
+
if (seenRoute.has(name)) continue;
|
|
29548
|
+
seenRoute.add(name);
|
|
29549
|
+
route.push({ name, files: [filePath], imports: [] });
|
|
29550
|
+
}
|
|
29551
|
+
return { service, route, ormModel };
|
|
29552
|
+
}
|
|
29553
|
+
var SERVICE_SUFFIXES5, SERVICE_SUFFIX_GROUP5, CPP_SERVICE_RE, CPP_CROW_ROUTE_RE, CPP_DROGON_ROUTE_RE, CPP_PISTACHE_ROUTE_RE;
|
|
29554
|
+
var init_cpp = __esm({
|
|
29555
|
+
"src/engine/visitors/cpp.ts"() {
|
|
29556
|
+
"use strict";
|
|
29557
|
+
SERVICE_SUFFIXES5 = [
|
|
29558
|
+
"Service",
|
|
29559
|
+
"Manager",
|
|
29560
|
+
"Handler",
|
|
29561
|
+
"Repository",
|
|
29562
|
+
"Controller",
|
|
29563
|
+
"Helper",
|
|
29564
|
+
"Factory",
|
|
29565
|
+
"Provider",
|
|
29566
|
+
"Store",
|
|
29567
|
+
"API",
|
|
29568
|
+
"Client",
|
|
29569
|
+
"Adapter",
|
|
29570
|
+
"Resolver",
|
|
29571
|
+
"Mapper",
|
|
29572
|
+
"Transformer",
|
|
29573
|
+
"Serializer",
|
|
29574
|
+
"Validator",
|
|
29575
|
+
"Strategy",
|
|
29576
|
+
"Facade",
|
|
29577
|
+
"Decorator",
|
|
29578
|
+
"Observer",
|
|
29579
|
+
"Builder",
|
|
29580
|
+
"Command",
|
|
29581
|
+
"Processor",
|
|
29582
|
+
"Worker",
|
|
29583
|
+
"Job"
|
|
29584
|
+
];
|
|
29585
|
+
SERVICE_SUFFIX_GROUP5 = `(?:${SERVICE_SUFFIXES5.join("|")})`;
|
|
29586
|
+
CPP_SERVICE_RE = new RegExp(
|
|
29587
|
+
`^(?:public\\s+|private\\s+|protected\\s+|virtual\\s+|abstract\\s+|static\\s+|inline\\s+|constexpr\\s+|explicit\\s+|final\\s+|extern\\s+)*(?:class|struct)\\s+(\\w+?)${SERVICE_SUFFIX_GROUP5}?\\b`,
|
|
29588
|
+
"gm"
|
|
29589
|
+
);
|
|
29590
|
+
CPP_CROW_ROUTE_RE = /CROW_ROUTE\s*\(\s*\w+\s*,\s*"(\/[^"]+)"/g;
|
|
29591
|
+
CPP_DROGON_ROUTE_RE = /\.registerHandler\(\s*"(\/[^"]+)"[\s,)]|\.\b(?:get|post|put|delete|patch)\(\s*"(\/[^"]+)"/g;
|
|
29592
|
+
CPP_PISTACHE_ROUTE_RE = /Routes::(?:get|post|put|delete|patch)\s*\(\s*[^,]+,\s*"(\/[^"]+)"/g;
|
|
29593
|
+
}
|
|
29594
|
+
});
|
|
29595
|
+
|
|
29596
|
+
// src/engine/visitors/java.ts
|
|
29597
|
+
var java_exports = {};
|
|
29598
|
+
__export(java_exports, {
|
|
29599
|
+
extractJavaPatterns: () => extractJavaPatterns
|
|
29600
|
+
});
|
|
29601
|
+
function extractJavaPatterns(filePath, source) {
|
|
29602
|
+
const service = [];
|
|
29603
|
+
const route = [];
|
|
29604
|
+
const ormModel = [];
|
|
29605
|
+
const seenService = /* @__PURE__ */ new Set();
|
|
29606
|
+
for (const m of source.matchAll(JAVA_SERVICE_RE)) {
|
|
29607
|
+
const name = m[1];
|
|
29608
|
+
if (seenService.has(name)) continue;
|
|
29609
|
+
seenService.add(name);
|
|
29610
|
+
service.push({ name, files: [filePath], imports: [] });
|
|
29611
|
+
}
|
|
29612
|
+
const seenRoute = /* @__PURE__ */ new Set();
|
|
29613
|
+
for (const m of source.matchAll(JAVA_SPRING_ROUTE_RE)) {
|
|
29614
|
+
const name = m[1];
|
|
29615
|
+
if (seenRoute.has(name)) continue;
|
|
29616
|
+
seenRoute.add(name);
|
|
29617
|
+
route.push({ name, files: [filePath], imports: [] });
|
|
29618
|
+
}
|
|
29619
|
+
for (const m of source.matchAll(JAVA_JAXRS_CLASS_PATH_RE)) {
|
|
29620
|
+
const name = m[1];
|
|
29621
|
+
if (name === "" || name === "/") continue;
|
|
29622
|
+
if (seenRoute.has(name)) continue;
|
|
29623
|
+
seenRoute.add(name);
|
|
29624
|
+
route.push({ name, files: [filePath], imports: [] });
|
|
29625
|
+
}
|
|
29626
|
+
const seenOrm = /* @__PURE__ */ new Set();
|
|
29627
|
+
for (const m of source.matchAll(JAVA_ORM_ANNOTATION_RE)) {
|
|
29628
|
+
const name = m[1];
|
|
29629
|
+
if (seenOrm.has(name)) continue;
|
|
29630
|
+
seenOrm.add(name);
|
|
29631
|
+
ormModel.push({ name, files: [filePath], imports: [] });
|
|
29632
|
+
}
|
|
29633
|
+
for (const m of source.matchAll(JAVA_ORM_INHERIT_RE)) {
|
|
29634
|
+
const name = m[1];
|
|
29635
|
+
if (seenOrm.has(name)) continue;
|
|
29636
|
+
seenOrm.add(name);
|
|
29637
|
+
ormModel.push({ name, files: [filePath], imports: [] });
|
|
29638
|
+
}
|
|
29639
|
+
return { service, route, ormModel };
|
|
29640
|
+
}
|
|
29641
|
+
var SERVICE_SUFFIXES6, SERVICE_SUFFIX_GROUP6, JAVA_SERVICE_RE, JAVA_SPRING_ROUTE_RE, JAVA_JAXRS_CLASS_PATH_RE, JAVA_ORM_ANNOTATION_RE, JAVA_ORM_INHERIT_RE;
|
|
29642
|
+
var init_java = __esm({
|
|
29643
|
+
"src/engine/visitors/java.ts"() {
|
|
29644
|
+
"use strict";
|
|
29645
|
+
SERVICE_SUFFIXES6 = [
|
|
29256
29646
|
"Service",
|
|
29257
29647
|
"Manager",
|
|
29258
29648
|
"Handler",
|
|
@@ -30963,6 +31353,246 @@ var init_broken_link = __esm({
|
|
|
30963
31353
|
}
|
|
30964
31354
|
});
|
|
30965
31355
|
|
|
31356
|
+
// src/rules/dup/identical-block.ts
|
|
31357
|
+
function normalizeAndHash(lines) {
|
|
31358
|
+
const normalized = lines.map(
|
|
31359
|
+
(line) => line.replace(/\/\/.*$/, "").replace(/\/\*[\s\S]*?\*\//g, "").replace(/\s+/g, " ").trim()
|
|
31360
|
+
).filter((line) => line.length > 0).join("\n");
|
|
31361
|
+
if (normalized.length < MIN_NORMALIZED_LENGTH) return void 0;
|
|
31362
|
+
return crypto.createHash("sha1").update(normalized).digest("hex").slice(0, HASH_PREFIX_LENGTH);
|
|
31363
|
+
}
|
|
31364
|
+
var crypto, WINDOW_SIZE, MIN_NORMALIZED_LENGTH, HASH_PREFIX_LENGTH, DEDUP_CACHE, dupIdenticalBlockRule;
|
|
31365
|
+
var init_identical_block = __esm({
|
|
31366
|
+
"src/rules/dup/identical-block.ts"() {
|
|
31367
|
+
"use strict";
|
|
31368
|
+
crypto = __toESM(require("crypto"), 1);
|
|
31369
|
+
init_rule();
|
|
31370
|
+
WINDOW_SIZE = 10;
|
|
31371
|
+
MIN_NORMALIZED_LENGTH = 40;
|
|
31372
|
+
HASH_PREFIX_LENGTH = 16;
|
|
31373
|
+
DEDUP_CACHE = /* @__PURE__ */ new Map();
|
|
31374
|
+
dupIdenticalBlockRule = createRule({
|
|
31375
|
+
id: "dup/identical-block",
|
|
31376
|
+
category: "logic",
|
|
31377
|
+
severity: "medium",
|
|
31378
|
+
aiSpecific: false,
|
|
31379
|
+
description: "Block of >=10 lines is identical across >=2 files (Type-1 clone detector)",
|
|
31380
|
+
create(_context) {
|
|
31381
|
+
return {};
|
|
31382
|
+
},
|
|
31383
|
+
analyze(_context, facts) {
|
|
31384
|
+
const issues = [];
|
|
31385
|
+
const source = facts.v2?._source;
|
|
31386
|
+
if (!source) return issues;
|
|
31387
|
+
const filePath = facts.filePath;
|
|
31388
|
+
const lines = source.split("\n");
|
|
31389
|
+
for (let i = 0; i <= lines.length - WINDOW_SIZE; i++) {
|
|
31390
|
+
const window = lines.slice(i, i + WINDOW_SIZE);
|
|
31391
|
+
const hash = normalizeAndHash(window);
|
|
31392
|
+
if (!hash) continue;
|
|
31393
|
+
const existing = DEDUP_CACHE.get(hash) ?? [];
|
|
31394
|
+
const matches = existing.filter((m) => m.file !== filePath);
|
|
31395
|
+
for (const match of matches) {
|
|
31396
|
+
issues.push({
|
|
31397
|
+
ruleId: "dup/identical-block",
|
|
31398
|
+
category: "logic",
|
|
31399
|
+
severity: "medium",
|
|
31400
|
+
aiSpecific: false,
|
|
31401
|
+
message: `Identical ${WINDOW_SIZE}-line block at line ${i + 1} also appears in ${match.file}:${match.line + 1}`,
|
|
31402
|
+
line: i + 1,
|
|
31403
|
+
column: 0,
|
|
31404
|
+
advice: "Refactor to a shared helper. This is a Type-1 clone (byte-for-byte identical after normalization). Common in AI-generated code that copy-pastes from training data.",
|
|
31405
|
+
extras: {
|
|
31406
|
+
duplicateOf: {
|
|
31407
|
+
file: match.file,
|
|
31408
|
+
line: match.line + 1,
|
|
31409
|
+
hash
|
|
31410
|
+
}
|
|
31411
|
+
}
|
|
31412
|
+
});
|
|
31413
|
+
}
|
|
31414
|
+
existing.push({ file: filePath, line: i });
|
|
31415
|
+
DEDUP_CACHE.set(hash, existing);
|
|
31416
|
+
}
|
|
31417
|
+
return issues;
|
|
31418
|
+
}
|
|
31419
|
+
});
|
|
31420
|
+
}
|
|
31421
|
+
});
|
|
31422
|
+
|
|
31423
|
+
// src/rules/go/error-wrap-without-context.ts
|
|
31424
|
+
var ERR_WRAP_REGEX, GENERIC_PREFIX_REGEX, goErrorWrapWithoutContextRule;
|
|
31425
|
+
var init_error_wrap_without_context = __esm({
|
|
31426
|
+
"src/rules/go/error-wrap-without-context.ts"() {
|
|
31427
|
+
"use strict";
|
|
31428
|
+
init_rule();
|
|
31429
|
+
ERR_WRAP_REGEX = /fmt\.Errorf\(\s*"((?:[^"\\]|\\.)*)"\s*,\s*([^)]+)\)/g;
|
|
31430
|
+
GENERIC_PREFIX_REGEX = /^\s*(?:error|err|failed|wrap(?:ping)?|invalid)\s*(?::\s*)?%w\b/i;
|
|
31431
|
+
goErrorWrapWithoutContextRule = createRule({
|
|
31432
|
+
id: "go/error-wrap-without-context",
|
|
31433
|
+
category: "typo",
|
|
31434
|
+
severity: "low",
|
|
31435
|
+
aiSpecific: true,
|
|
31436
|
+
description: 'fmt.Errorf wrap without operation context \u2014 AI defaults to generic "error: %w"',
|
|
31437
|
+
create(_context) {
|
|
31438
|
+
return {};
|
|
31439
|
+
},
|
|
31440
|
+
analyze(_context, facts) {
|
|
31441
|
+
const issues = [];
|
|
31442
|
+
const source = facts.v2?._source;
|
|
31443
|
+
if (!source) return issues;
|
|
31444
|
+
let match;
|
|
31445
|
+
ERR_WRAP_REGEX.lastIndex = 0;
|
|
31446
|
+
while ((match = ERR_WRAP_REGEX.exec(source)) !== null) {
|
|
31447
|
+
const formatString = match[1];
|
|
31448
|
+
if (!formatString.includes("%w")) continue;
|
|
31449
|
+
if (formatString.length >= 30) continue;
|
|
31450
|
+
if (!GENERIC_PREFIX_REGEX.test(formatString)) continue;
|
|
31451
|
+
const line = source.slice(0, match.index).split("\n").length;
|
|
31452
|
+
issues.push({
|
|
31453
|
+
ruleId: "go/error-wrap-without-context",
|
|
31454
|
+
category: "typo",
|
|
31455
|
+
severity: "low",
|
|
31456
|
+
aiSpecific: true,
|
|
31457
|
+
message: `fmt.Errorf wrap with generic message "${formatString}" \u2014 include the failing operation`,
|
|
31458
|
+
line,
|
|
31459
|
+
column: match[0].indexOf("fmt") + 1,
|
|
31460
|
+
advice: 'Real Go errors include the failing operation: `fmt.Errorf("opening config: %w", err)`. Generic messages ("error: %w", "failed: %w") tell the reader nothing about what failed. Reference: go/error-wrap-without-context v0.19. See: https://github.com/golang/go/wiki/CodeReviewComments#error-strings'
|
|
31461
|
+
});
|
|
31462
|
+
}
|
|
31463
|
+
return issues;
|
|
31464
|
+
}
|
|
31465
|
+
});
|
|
31466
|
+
}
|
|
31467
|
+
});
|
|
31468
|
+
|
|
31469
|
+
// src/rules/go/nil-slice-vs-empty.ts
|
|
31470
|
+
var NIL_SLICE_DECL_REGEX, EMPTY_SLICE_ASSIGN_REGEX, goNilSliceVsEmptyRule;
|
|
31471
|
+
var init_nil_slice_vs_empty = __esm({
|
|
31472
|
+
"src/rules/go/nil-slice-vs-empty.ts"() {
|
|
31473
|
+
"use strict";
|
|
31474
|
+
init_rule();
|
|
31475
|
+
NIL_SLICE_DECL_REGEX = /^[\t ]*var\s+([A-Za-z_][A-Za-z0-9_]*)\s+\[\][\w.*]+\b/gm;
|
|
31476
|
+
EMPTY_SLICE_ASSIGN_REGEX = /^[\t ]*([A-Za-z_][A-Za-z0-9_]*)\s*=\s*(?:\[\][\w.*]*\{\}|make\(\[\][\w.*]*)/gm;
|
|
31477
|
+
goNilSliceVsEmptyRule = createRule({
|
|
31478
|
+
id: "go/nil-slice-vs-empty",
|
|
31479
|
+
category: "typo",
|
|
31480
|
+
severity: "low",
|
|
31481
|
+
aiSpecific: true,
|
|
31482
|
+
description: "Variable declared `var x []int` but later assigned `x = []int{}` or `make([]int, n)` \u2014 pick one form",
|
|
31483
|
+
create(_context) {
|
|
31484
|
+
return {};
|
|
31485
|
+
},
|
|
31486
|
+
analyze(_context, facts) {
|
|
31487
|
+
const issues = [];
|
|
31488
|
+
const source = facts.v2?._source;
|
|
31489
|
+
if (!source) return issues;
|
|
31490
|
+
const nilDecls = /* @__PURE__ */ new Map();
|
|
31491
|
+
let m;
|
|
31492
|
+
NIL_SLICE_DECL_REGEX.lastIndex = 0;
|
|
31493
|
+
while ((m = NIL_SLICE_DECL_REGEX.exec(source)) !== null) {
|
|
31494
|
+
nilDecls.set(m[1], source.slice(0, m.index).split("\n").length);
|
|
31495
|
+
}
|
|
31496
|
+
if (nilDecls.size === 0) return issues;
|
|
31497
|
+
EMPTY_SLICE_ASSIGN_REGEX.lastIndex = 0;
|
|
31498
|
+
while ((m = EMPTY_SLICE_ASSIGN_REGEX.exec(source)) !== null) {
|
|
31499
|
+
const name = m[1];
|
|
31500
|
+
if (!nilDecls.has(name)) continue;
|
|
31501
|
+
const declLine = nilDecls.get(name);
|
|
31502
|
+
const assignLine = source.slice(0, m.index).split("\n").length;
|
|
31503
|
+
if (assignLine <= declLine) continue;
|
|
31504
|
+
issues.push({
|
|
31505
|
+
ruleId: "go/nil-slice-vs-empty",
|
|
31506
|
+
category: "typo",
|
|
31507
|
+
severity: "low",
|
|
31508
|
+
aiSpecific: true,
|
|
31509
|
+
message: `Variable '${name}' declared as nil slice (line ${declLine}) but assigned an empty slice (line ${assignLine}) \u2014 pick one form`,
|
|
31510
|
+
line: declLine,
|
|
31511
|
+
column: 1,
|
|
31512
|
+
advice: "Either declare as `var " + name + " = []int{}` or assign with `make([]int, 0)`. The nil/empty inconsistency is an AI signal \u2014 real code picks one form and sticks with it. Reference: go/nil-slice-vs-empty v0.19."
|
|
31513
|
+
});
|
|
31514
|
+
}
|
|
31515
|
+
return issues;
|
|
31516
|
+
}
|
|
31517
|
+
});
|
|
31518
|
+
}
|
|
31519
|
+
});
|
|
31520
|
+
|
|
31521
|
+
// src/rules/go/struct-tag-inconsistency.ts
|
|
31522
|
+
var JSON_TAG_REGEX, goStructTagInconsistencyRule;
|
|
31523
|
+
var init_struct_tag_inconsistency = __esm({
|
|
31524
|
+
"src/rules/go/struct-tag-inconsistency.ts"() {
|
|
31525
|
+
"use strict";
|
|
31526
|
+
init_rule();
|
|
31527
|
+
JSON_TAG_REGEX = /`json:"([^",]+)(?:,([^"]+))?"`/g;
|
|
31528
|
+
goStructTagInconsistencyRule = createRule({
|
|
31529
|
+
id: "go/struct-tag-inconsistency",
|
|
31530
|
+
category: "typo",
|
|
31531
|
+
severity: "low",
|
|
31532
|
+
aiSpecific: true,
|
|
31533
|
+
description: 'Struct fields mix json:"foo" and json:"foo,omitempty" \u2014 pick one convention per struct',
|
|
31534
|
+
create(_context) {
|
|
31535
|
+
return {};
|
|
31536
|
+
},
|
|
31537
|
+
analyze(_context, facts) {
|
|
31538
|
+
const issues = [];
|
|
31539
|
+
const source = facts.v2?._source;
|
|
31540
|
+
if (!source) return issues;
|
|
31541
|
+
const structRegex = /type\s+[A-Z][A-Za-z0-9_]*\s+struct\s*\{/g;
|
|
31542
|
+
let structMatch;
|
|
31543
|
+
while ((structMatch = structRegex.exec(source)) !== null) {
|
|
31544
|
+
const startIdx = structMatch.index;
|
|
31545
|
+
const openBrace = source.indexOf("{", startIdx);
|
|
31546
|
+
if (openBrace < 0) continue;
|
|
31547
|
+
let depth = 1;
|
|
31548
|
+
let i = openBrace + 1;
|
|
31549
|
+
while (i < source.length && depth > 0) {
|
|
31550
|
+
const ch = source[i];
|
|
31551
|
+
if (ch === "{") depth++;
|
|
31552
|
+
else if (ch === "}") depth--;
|
|
31553
|
+
i++;
|
|
31554
|
+
}
|
|
31555
|
+
const structBody = source.slice(openBrace, i);
|
|
31556
|
+
const structLine = source.slice(0, startIdx).split("\n").length;
|
|
31557
|
+
const styleCount = {};
|
|
31558
|
+
const tagMatches = [];
|
|
31559
|
+
let m;
|
|
31560
|
+
JSON_TAG_REGEX.lastIndex = 0;
|
|
31561
|
+
while ((m = JSON_TAG_REGEX.exec(structBody)) !== null) {
|
|
31562
|
+
const tag = m[1];
|
|
31563
|
+
const options = m[2] ?? "";
|
|
31564
|
+
const style = options ? "with-options" : "no-options";
|
|
31565
|
+
styleCount[style] = (styleCount[style] ?? 0) + 1;
|
|
31566
|
+
tagMatches.push({ tag, style, idx: openBrace + m.index });
|
|
31567
|
+
}
|
|
31568
|
+
const styles = Object.keys(styleCount);
|
|
31569
|
+
if (styles.length < 2 || tagMatches.length < 2) continue;
|
|
31570
|
+
const dominant = styles.reduce(
|
|
31571
|
+
(a, b) => (styleCount[a] ?? 0) >= (styleCount[b] ?? 0) ? a : b
|
|
31572
|
+
);
|
|
31573
|
+
const minority = tagMatches.filter((t) => t.style !== dominant);
|
|
31574
|
+
if (minority.length === 0) continue;
|
|
31575
|
+
for (const m2 of minority) {
|
|
31576
|
+
const line = source.slice(0, m2.idx).split("\n").length;
|
|
31577
|
+
issues.push({
|
|
31578
|
+
ruleId: "go/struct-tag-inconsistency",
|
|
31579
|
+
category: "typo",
|
|
31580
|
+
severity: "low",
|
|
31581
|
+
aiSpecific: true,
|
|
31582
|
+
message: `Struct mixes json tag styles \u2014 this field uses "json:"${m2.tag}${m2.style === "with-options" ? ",..." : ""}"" but the dominant style is ${dominant === "with-options" ? "with options (e.g. omitempty)" : "no options"}`,
|
|
31583
|
+
line,
|
|
31584
|
+
column: 1,
|
|
31585
|
+
advice: 'Pick one tag style per struct. If most fields are `json:"foo"`, this field should be too. Real Go code maintains consistency within a struct (or within a package). Reference: go/struct-tag-inconsistency v0.19.'
|
|
31586
|
+
});
|
|
31587
|
+
}
|
|
31588
|
+
if (issues.length > 0) break;
|
|
31589
|
+
}
|
|
31590
|
+
return issues;
|
|
31591
|
+
}
|
|
31592
|
+
});
|
|
31593
|
+
}
|
|
31594
|
+
});
|
|
31595
|
+
|
|
30966
31596
|
// src/rules/layout/gap-monopoly.ts
|
|
30967
31597
|
var GAP_RE, gapMonopolyRule;
|
|
30968
31598
|
var init_gap_monopoly = __esm({
|
|
@@ -36060,7 +36690,7 @@ function parseBlankModule(source) {
|
|
|
36060
36690
|
tsx: false,
|
|
36061
36691
|
target: "es2022"
|
|
36062
36692
|
});
|
|
36063
|
-
return { ast, source
|
|
36693
|
+
return { ast, source };
|
|
36064
36694
|
}
|
|
36065
36695
|
function parseScriptContent(content, isTypeScript) {
|
|
36066
36696
|
if (isTypeScript) {
|
|
@@ -36146,8 +36776,16 @@ function parseSource(source, filePath) {
|
|
|
36146
36776
|
// but no SWC support. Return a blank-padded empty module so
|
|
36147
36777
|
// regex-only rules can still fire (markdown-leakage, comment-
|
|
36148
36778
|
// ratio, etc.) without burning the parseError path.
|
|
36779
|
+
// v0.18.9: `.rs` is in the same bucket. The visitor layer
|
|
36780
|
+
// (`engine/visitors/rust.ts`) carries the tree-sitter-backed
|
|
36781
|
+
// parse + extractFacts attaches the result to `facts.v2.rustFile`.
|
|
36782
|
+
// The rule layer (`rules/rust/*.ts`) reads that field. parseBlankModule
|
|
36783
|
+
// lets the worker continue past the parser — without this, parseWithSwc
|
|
36784
|
+
// would throw on every .rs file, the worker would count it as a
|
|
36785
|
+
// parseError, and the v2-build's buildRustFileRecord would never run.
|
|
36149
36786
|
case "py":
|
|
36150
36787
|
case "go":
|
|
36788
|
+
case "rs":
|
|
36151
36789
|
return parseBlankModule(source);
|
|
36152
36790
|
default:
|
|
36153
36791
|
return parseWithSwc(source, filePath);
|
|
@@ -38243,91 +38881,6 @@ var init_key_prop_missing = __esm({
|
|
|
38243
38881
|
}
|
|
38244
38882
|
});
|
|
38245
38883
|
|
|
38246
|
-
// src/rules/logic/ks-distribution-shift.ts
|
|
38247
|
-
function extractFileFeatures(source) {
|
|
38248
|
-
const lines = source.split("\n");
|
|
38249
|
-
const lineLengths = lines.map((l) => l.length);
|
|
38250
|
-
const identifierLengths = [];
|
|
38251
|
-
const idRe = /[A-Za-z_$][A-Za-z0-9_$]*/g;
|
|
38252
|
-
let m;
|
|
38253
|
-
while ((m = idRe.exec(source)) !== null) {
|
|
38254
|
-
identifierLengths.push(m[0].length);
|
|
38255
|
-
}
|
|
38256
|
-
const commentDensity = lines.map((l) => {
|
|
38257
|
-
const trimmed = l.trim();
|
|
38258
|
-
if (trimmed.length === 0) return 0;
|
|
38259
|
-
const commentChars = (trimmed.match(/^\/\/.*$/)?.[0]?.length ?? 0) + (trimmed.match(/^\s*\/\*.*?\*\/\s*$/)?.at(0)?.length ?? 0);
|
|
38260
|
-
return commentChars / trimmed.length;
|
|
38261
|
-
});
|
|
38262
|
-
return { lineLengths, identifierLengths, commentDensity };
|
|
38263
|
-
}
|
|
38264
|
-
var MIN_SAMPLES_PER_FEATURE, ksDistributionShiftRule;
|
|
38265
|
-
var init_ks_distribution_shift = __esm({
|
|
38266
|
-
"src/rules/logic/ks-distribution-shift.ts"() {
|
|
38267
|
-
"use strict";
|
|
38268
|
-
init_rule();
|
|
38269
|
-
init_dist2();
|
|
38270
|
-
init_corpus_baselines2();
|
|
38271
|
-
MIN_SAMPLES_PER_FEATURE = 20;
|
|
38272
|
-
ksDistributionShiftRule = createRule({
|
|
38273
|
-
id: "logic/ks-distribution-shift",
|
|
38274
|
-
category: "logic",
|
|
38275
|
-
severity: "medium",
|
|
38276
|
-
aiSpecific: false,
|
|
38277
|
-
description: "Multi-feature Kolmogorov\u2013Smirnov distribution-shift vs corpus baseline (Bonferroni-corrected). Peer-reviewed ML distribution-shift detector (arXiv:2510.15996, Oct 2025).",
|
|
38278
|
-
create(context) {
|
|
38279
|
-
return context;
|
|
38280
|
-
},
|
|
38281
|
-
analyze(_context, facts) {
|
|
38282
|
-
const issues = [];
|
|
38283
|
-
if (!facts.v2) return issues;
|
|
38284
|
-
const source = facts.v2._source ?? "";
|
|
38285
|
-
if (source.length < 200) return issues;
|
|
38286
|
-
const features = extractFileFeatures(source);
|
|
38287
|
-
const samples = /* @__PURE__ */ new Map([
|
|
38288
|
-
["lineLengths", features.lineLengths],
|
|
38289
|
-
["identifierLengths", features.identifierLengths],
|
|
38290
|
-
["commentDensity", features.commentDensity]
|
|
38291
|
-
]);
|
|
38292
|
-
const baselines = getCorpusBaselines();
|
|
38293
|
-
const baselinesMap = /* @__PURE__ */ new Map();
|
|
38294
|
-
if (baselines) {
|
|
38295
|
-
baselinesMap.set("lineLengths", baselines.features.lineLengths.sample);
|
|
38296
|
-
baselinesMap.set("identifierLengths", baselines.features.identifierLengths.sample);
|
|
38297
|
-
baselinesMap.set("commentDensity", baselines.features.commentDensity.sample);
|
|
38298
|
-
} else {
|
|
38299
|
-
baselinesMap.set("lineLengths", [20, 25, 30, 32, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95, 100]);
|
|
38300
|
-
baselinesMap.set("identifierLengths", [3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 18, 20, 24, 28]);
|
|
38301
|
-
baselinesMap.set("commentDensity", [0, 0, 0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.4, 0.5]);
|
|
38302
|
-
}
|
|
38303
|
-
for (const [name, vals] of samples) {
|
|
38304
|
-
if (vals.length < MIN_SAMPLES_PER_FEATURE) samples.delete(name);
|
|
38305
|
-
}
|
|
38306
|
-
if (samples.size === 0) return issues;
|
|
38307
|
-
const result = multiFeatureKsTest(samples, baselinesMap, 0.05);
|
|
38308
|
-
if (!result.anySignificant) return issues;
|
|
38309
|
-
const shifted = result.significantFeatures.join(", ");
|
|
38310
|
-
const details = result.significantFeatures.map((name) => {
|
|
38311
|
-
const r = result.perFeature.get(name);
|
|
38312
|
-
if (!r) return name;
|
|
38313
|
-
return `${name} (D=${r.statistic.toFixed(3)}, p=${r.pValue.toExponential(2)})`;
|
|
38314
|
-
}).join("; ");
|
|
38315
|
-
issues.push({
|
|
38316
|
-
ruleId: "logic/ks-distribution-shift",
|
|
38317
|
-
category: "logic",
|
|
38318
|
-
severity: "medium",
|
|
38319
|
-
aiSpecific: true,
|
|
38320
|
-
message: `Distribution shift detected on ${result.significantFeatures.length} of ${result.perFeature.size} features (Bonferroni \u03B1=${result.bonferroniAlpha.toExponential(2)}). Features: ${shifted}. Detail: ${details}.`,
|
|
38321
|
-
line: 1,
|
|
38322
|
-
column: 1,
|
|
38323
|
-
advice: "Inspect the shifted features. KS detects both AI anomalies and production-rot anomalies (it is symmetric); combine with Heaps/Zipf for AI-specific signal."
|
|
38324
|
-
});
|
|
38325
|
-
return issues;
|
|
38326
|
-
}
|
|
38327
|
-
});
|
|
38328
|
-
}
|
|
38329
|
-
});
|
|
38330
|
-
|
|
38331
38884
|
// src/rules/logic/math-any-density.ts
|
|
38332
38885
|
var ANY_PER_100_LINES, MIN_ABSOLUTE, COLON, ANY_KEYWORD, ANY_TYPE_RE, MSG_FRAGMENT, RULE_DESCRIPTION, RULE_MESSAGE, RULE_ADVICE, mathAnyDensityRule;
|
|
38333
38886
|
var init_math_any_density = __esm({
|
|
@@ -38397,13 +38950,13 @@ var init_math_any_density = __esm({
|
|
|
38397
38950
|
});
|
|
38398
38951
|
|
|
38399
38952
|
// src/rules/logic/math-console-log-storm.ts
|
|
38400
|
-
var
|
|
38953
|
+
var WINDOW_SIZE2, STORM_THRESHOLD, CONSOLE_LOG_RE, mathConsoleLogStormRule;
|
|
38401
38954
|
var init_math_console_log_storm = __esm({
|
|
38402
38955
|
"src/rules/logic/math-console-log-storm.ts"() {
|
|
38403
38956
|
"use strict";
|
|
38404
38957
|
init_rule();
|
|
38405
38958
|
init_utils();
|
|
38406
|
-
|
|
38959
|
+
WINDOW_SIZE2 = 30;
|
|
38407
38960
|
STORM_THRESHOLD = 5;
|
|
38408
38961
|
CONSOLE_LOG_RE = /\bconsole\.log\s*\(/g;
|
|
38409
38962
|
mathConsoleLogStormRule = createRule({
|
|
@@ -38434,7 +38987,7 @@ var init_math_console_log_storm = __esm({
|
|
|
38434
38987
|
let maxEndLine = 0;
|
|
38435
38988
|
let i = 0;
|
|
38436
38989
|
for (let j = 0; j < lines.length; j++) {
|
|
38437
|
-
while (lines[j] - lines[i] >
|
|
38990
|
+
while (lines[j] - lines[i] > WINDOW_SIZE2) i++;
|
|
38438
38991
|
const count = j - i + 1;
|
|
38439
38992
|
if (count > maxCount) {
|
|
38440
38993
|
maxCount = count;
|
|
@@ -38448,7 +39001,7 @@ var init_math_console_log_storm = __esm({
|
|
|
38448
39001
|
category: "logic",
|
|
38449
39002
|
severity: "high",
|
|
38450
39003
|
aiSpecific: true,
|
|
38451
|
-
message: `${maxCount} console.log calls clustered in a ${
|
|
39004
|
+
message: `${maxCount} console.log calls clustered in a ${WINDOW_SIZE2}-line window ending at line ${maxEndLine}. AI debug-sprays logs in a single function; humans use one strategic log.`,
|
|
38452
39005
|
line: firstIdx >= 0 ? lines[firstIdx] : 1,
|
|
38453
39006
|
column: firstIdx >= 0 ? columns[firstIdx] : 1,
|
|
38454
39007
|
advice: "Replace debug logs with a proper debugger or logger.debug() \u2014 remove all console.log before shipping."
|
|
@@ -39334,6 +39887,354 @@ var init_ux_pattern_fragmentation = __esm({
|
|
|
39334
39887
|
}
|
|
39335
39888
|
});
|
|
39336
39889
|
|
|
39890
|
+
// src/rules/rust/stringly-typed.ts
|
|
39891
|
+
function collectEnumCandidates(source) {
|
|
39892
|
+
const out = [];
|
|
39893
|
+
const enumRe = /^(?:pub(?:\([^)]+\))?\s+)?enum\s+(\w+)\s*\{([^}]*)\}/gm;
|
|
39894
|
+
for (const m of source.matchAll(enumRe)) {
|
|
39895
|
+
const body = m[2] ?? "";
|
|
39896
|
+
const variants = body.split(/,(?![^()]*\))/).map((s) => s.trim()).filter((s) => /^[A-Za-z_][A-Za-z0-9_]*$/.test(s.split(/\s+/)[0] ?? ""));
|
|
39897
|
+
if (variants.length > MAX_VARIANT_COUNT) continue;
|
|
39898
|
+
if (variants.length < 2) continue;
|
|
39899
|
+
out.push({ name: m[1], variantCount: variants.length, line: lineOfMatch(source, m.index ?? 0) });
|
|
39900
|
+
}
|
|
39901
|
+
return out;
|
|
39902
|
+
}
|
|
39903
|
+
function lineOfMatch(source, index) {
|
|
39904
|
+
let line = 1;
|
|
39905
|
+
for (let i = 0; i < index && i < source.length; i++) {
|
|
39906
|
+
if (source[i] === "\n") line++;
|
|
39907
|
+
}
|
|
39908
|
+
return line;
|
|
39909
|
+
}
|
|
39910
|
+
function buildLineOffsets(source) {
|
|
39911
|
+
const out = [0];
|
|
39912
|
+
for (let i = 0; i < source.length; i++) {
|
|
39913
|
+
if (source[i] === "\n") out.push(i + 1);
|
|
39914
|
+
}
|
|
39915
|
+
return out;
|
|
39916
|
+
}
|
|
39917
|
+
function extractParameterText(source, lineOffsets, fn) {
|
|
39918
|
+
const start = lineOffsets[Math.max(0, fn.line - 1)] ?? 0;
|
|
39919
|
+
const head = source.slice(start, start + 400);
|
|
39920
|
+
const openIdx = head.indexOf("(");
|
|
39921
|
+
if (openIdx < 0) return "";
|
|
39922
|
+
let closeIdx = -1;
|
|
39923
|
+
let depth = 0;
|
|
39924
|
+
for (let i = openIdx; i < head.length; i++) {
|
|
39925
|
+
if (head[i] === "(") depth++;
|
|
39926
|
+
else if (head[i] === ")") {
|
|
39927
|
+
depth--;
|
|
39928
|
+
if (depth === 0) {
|
|
39929
|
+
closeIdx = i;
|
|
39930
|
+
break;
|
|
39931
|
+
}
|
|
39932
|
+
}
|
|
39933
|
+
}
|
|
39934
|
+
if (closeIdx < 0) return "";
|
|
39935
|
+
return head.slice(openIdx + 1, closeIdx);
|
|
39936
|
+
}
|
|
39937
|
+
function scanForStringlyParams(paramText) {
|
|
39938
|
+
const out = [];
|
|
39939
|
+
for (const m of paramText.matchAll(
|
|
39940
|
+
/\b([a-z_][a-zA-Z0-9_]*)\s*:\s*(&\s*(?:mut\s+)?(?:str|String)\b)/g
|
|
39941
|
+
)) {
|
|
39942
|
+
const name = m[1];
|
|
39943
|
+
const type = m[2];
|
|
39944
|
+
if (!SUSPECT_PARAM_NAMES.has(name)) continue;
|
|
39945
|
+
out.push({ name, type });
|
|
39946
|
+
}
|
|
39947
|
+
return out;
|
|
39948
|
+
}
|
|
39949
|
+
var SUSPECT_PARAM_NAMES, MAX_VARIANT_COUNT, rustStringlyTypedRule;
|
|
39950
|
+
var init_stringly_typed = __esm({
|
|
39951
|
+
"src/rules/rust/stringly-typed.ts"() {
|
|
39952
|
+
"use strict";
|
|
39953
|
+
init_rule();
|
|
39954
|
+
SUSPECT_PARAM_NAMES = /* @__PURE__ */ new Set([
|
|
39955
|
+
"kind",
|
|
39956
|
+
"type",
|
|
39957
|
+
"mode",
|
|
39958
|
+
"event",
|
|
39959
|
+
"status",
|
|
39960
|
+
"category",
|
|
39961
|
+
"action",
|
|
39962
|
+
"state",
|
|
39963
|
+
"level",
|
|
39964
|
+
"role",
|
|
39965
|
+
"tier",
|
|
39966
|
+
"phase",
|
|
39967
|
+
"tag",
|
|
39968
|
+
"format",
|
|
39969
|
+
"shape",
|
|
39970
|
+
"direction",
|
|
39971
|
+
"side",
|
|
39972
|
+
"method"
|
|
39973
|
+
]);
|
|
39974
|
+
MAX_VARIANT_COUNT = 32;
|
|
39975
|
+
rustStringlyTypedRule = createRule({
|
|
39976
|
+
id: "rust/stringly-typed",
|
|
39977
|
+
category: "logic",
|
|
39978
|
+
severity: "medium",
|
|
39979
|
+
aiSpecific: true,
|
|
39980
|
+
description: "String / &str parameter where a typed enum exists in the same file",
|
|
39981
|
+
create(_context) {
|
|
39982
|
+
return {};
|
|
39983
|
+
},
|
|
39984
|
+
analyze(_context, facts) {
|
|
39985
|
+
const issues = [];
|
|
39986
|
+
if (!facts.v2?.rustFile) return issues;
|
|
39987
|
+
const source = facts.v2._source ?? "";
|
|
39988
|
+
if (!source) return issues;
|
|
39989
|
+
const lineOffsets = buildLineOffsets(source);
|
|
39990
|
+
const enumCandidates = collectEnumCandidates(source);
|
|
39991
|
+
if (enumCandidates.length === 0) return issues;
|
|
39992
|
+
for (const fn of facts.v2.rustFile.functions) {
|
|
39993
|
+
const paramText = extractParameterText(source, lineOffsets, fn);
|
|
39994
|
+
if (!paramText) continue;
|
|
39995
|
+
const matches = scanForStringlyParams(paramText);
|
|
39996
|
+
if (matches.length === 0) continue;
|
|
39997
|
+
issues.push({
|
|
39998
|
+
ruleId: "rust/stringly-typed",
|
|
39999
|
+
category: "logic",
|
|
40000
|
+
severity: "medium",
|
|
40001
|
+
aiSpecific: true,
|
|
40002
|
+
message: matches.length === 1 ? `Parameter '${matches[0].name}' typed as '${matches[0].type}', but enum ${enumCandidates[0].name} exists in the file` : `Function has ${matches.length} stringly-typed parameters; enum ${enumCandidates[0].name} exists in the file`,
|
|
40003
|
+
line: fn.line,
|
|
40004
|
+
column: fn.column,
|
|
40005
|
+
advice: `Replace the String/&str parameter with the typed enum. Stringly-typed APIs lose type information at the boundary; a typo ('Click' vs 'click') only fails at runtime. AI agents introduce these during exploratory scaffolding, then never replace them with the existing enum.`
|
|
40006
|
+
});
|
|
40007
|
+
}
|
|
40008
|
+
return issues;
|
|
40009
|
+
}
|
|
40010
|
+
});
|
|
40011
|
+
}
|
|
40012
|
+
});
|
|
40013
|
+
|
|
40014
|
+
// src/rules/rust/todo-macro.ts
|
|
40015
|
+
function collectMacroIssues(node, testScopes, issues) {
|
|
40016
|
+
if (node.type === "macro_invocation") {
|
|
40017
|
+
const text = node.text;
|
|
40018
|
+
const m = text.match(/^([A-Za-z_][A-Za-z0-9_]*)/);
|
|
40019
|
+
const macroName = m?.[1] ?? "";
|
|
40020
|
+
if (TODO_MACROS.has(macroName)) {
|
|
40021
|
+
if (!isInsideMacroDefinition(node) && !isInsideTestFunction(node, testScopes)) {
|
|
40022
|
+
issues.push({
|
|
40023
|
+
ruleId: "rust/todo-macro",
|
|
40024
|
+
category: "logic",
|
|
40025
|
+
severity: "medium",
|
|
40026
|
+
aiSpecific: true,
|
|
40027
|
+
message: `'${macroName}!()' in production code \u2014 both expand to panic!()`,
|
|
40028
|
+
line: node.startPosition.row + 1,
|
|
40029
|
+
column: node.startPosition.column,
|
|
40030
|
+
advice: `Implement the function body or remove the stub. '${macroName}!()' is fine in test scaffolding (#[cfg(test)]); here it is a panic risk. AI agents commonly leave these behind after iterative refactors when the placeholder branch is never filled in.`
|
|
40031
|
+
});
|
|
40032
|
+
}
|
|
40033
|
+
}
|
|
40034
|
+
}
|
|
40035
|
+
for (let i = 0; i < node.namedChildCount; i++) {
|
|
40036
|
+
const child = node.namedChild(i);
|
|
40037
|
+
if (child) collectMacroIssues(child, testScopes, issues);
|
|
40038
|
+
}
|
|
40039
|
+
}
|
|
40040
|
+
function isInsideMacroDefinition(node) {
|
|
40041
|
+
for (let p = node.parent; p; p = p.parent) {
|
|
40042
|
+
if (p.type === "macro_definition") return true;
|
|
40043
|
+
if (p.type === "source_file") return false;
|
|
40044
|
+
}
|
|
40045
|
+
return false;
|
|
40046
|
+
}
|
|
40047
|
+
function isInsideTestFunction(node, testScopes) {
|
|
40048
|
+
for (let p = node.parent; p; p = p.parent) {
|
|
40049
|
+
if (p.type === "function_item") {
|
|
40050
|
+
const nameField = p.childForFieldName("name");
|
|
40051
|
+
const name = nameField?.text;
|
|
40052
|
+
if (name && testScopes.has(name)) return true;
|
|
40053
|
+
if (p.text.startsWith("#[test]") || p.text.startsWith("#[cfg(test)]")) return true;
|
|
40054
|
+
return false;
|
|
40055
|
+
}
|
|
40056
|
+
if (p.type === "source_file") return false;
|
|
40057
|
+
}
|
|
40058
|
+
return false;
|
|
40059
|
+
}
|
|
40060
|
+
var TODO_MACROS, rustTodoMacroRule;
|
|
40061
|
+
var init_todo_macro = __esm({
|
|
40062
|
+
"src/rules/rust/todo-macro.ts"() {
|
|
40063
|
+
"use strict";
|
|
40064
|
+
init_rule();
|
|
40065
|
+
init_parser_rust();
|
|
40066
|
+
TODO_MACROS = /* @__PURE__ */ new Set(["todo", "unimplemented", "todo_unimplemented"]);
|
|
40067
|
+
rustTodoMacroRule = createRule({
|
|
40068
|
+
id: "rust/todo-macro",
|
|
40069
|
+
category: "logic",
|
|
40070
|
+
severity: "medium",
|
|
40071
|
+
aiSpecific: true,
|
|
40072
|
+
description: "todo!() / unimplemented!() macro invocation in production code",
|
|
40073
|
+
create(_context) {
|
|
40074
|
+
return {};
|
|
40075
|
+
},
|
|
40076
|
+
analyze(_context, facts) {
|
|
40077
|
+
const issues = [];
|
|
40078
|
+
if (!facts.v2?.rustFile) return issues;
|
|
40079
|
+
const source = facts.v2._source ?? "";
|
|
40080
|
+
if (!source) return issues;
|
|
40081
|
+
const tree = parseRust(source);
|
|
40082
|
+
if (!tree) return issues;
|
|
40083
|
+
const testScopes = /* @__PURE__ */ new Set();
|
|
40084
|
+
for (const fn of facts.v2.rustFile.functions) {
|
|
40085
|
+
if (fn.inTestConfig && fn.name) testScopes.add(fn.name);
|
|
40086
|
+
}
|
|
40087
|
+
collectMacroIssues(tree.rootNode, testScopes, issues);
|
|
40088
|
+
return issues;
|
|
40089
|
+
}
|
|
40090
|
+
});
|
|
40091
|
+
}
|
|
40092
|
+
});
|
|
40093
|
+
|
|
40094
|
+
// src/rules/rust/unused-pub-fn.ts
|
|
40095
|
+
function collectReferencedNames(source) {
|
|
40096
|
+
const out = /* @__PURE__ */ new Set();
|
|
40097
|
+
for (const m of source.matchAll(/\b([A-Za-z_][A-Za-z0-9_]*)\b/g)) {
|
|
40098
|
+
out.add(m[1]);
|
|
40099
|
+
}
|
|
40100
|
+
return out;
|
|
40101
|
+
}
|
|
40102
|
+
var API_CONVENTION_NAMES, rustUnusedPubFnRule;
|
|
40103
|
+
var init_unused_pub_fn = __esm({
|
|
40104
|
+
"src/rules/rust/unused-pub-fn.ts"() {
|
|
40105
|
+
"use strict";
|
|
40106
|
+
init_rule();
|
|
40107
|
+
API_CONVENTION_NAMES = /* @__PURE__ */ new Set([
|
|
40108
|
+
"new",
|
|
40109
|
+
"default",
|
|
40110
|
+
"from",
|
|
40111
|
+
"from_str",
|
|
40112
|
+
"from_iter",
|
|
40113
|
+
"try_from",
|
|
40114
|
+
"into",
|
|
40115
|
+
"into_iter",
|
|
40116
|
+
"try_into",
|
|
40117
|
+
"as_ref",
|
|
40118
|
+
"as_mut",
|
|
40119
|
+
"clone",
|
|
40120
|
+
"fmt",
|
|
40121
|
+
"eq",
|
|
40122
|
+
"hash",
|
|
40123
|
+
"partial_cmp",
|
|
40124
|
+
"cmp",
|
|
40125
|
+
"ord",
|
|
40126
|
+
"partial_eq"
|
|
40127
|
+
]);
|
|
40128
|
+
rustUnusedPubFnRule = createRule({
|
|
40129
|
+
id: "rust/unused-pub-fn",
|
|
40130
|
+
category: "logic",
|
|
40131
|
+
severity: "low",
|
|
40132
|
+
aiSpecific: true,
|
|
40133
|
+
description: "Public function in a Rust file that has no in-file references",
|
|
40134
|
+
create(_context) {
|
|
40135
|
+
return {};
|
|
40136
|
+
},
|
|
40137
|
+
analyze(_context, facts) {
|
|
40138
|
+
const issues = [];
|
|
40139
|
+
if (!facts.v2?.rustFile) return issues;
|
|
40140
|
+
const rust = facts.v2.rustFile;
|
|
40141
|
+
const referenced = collectReferencedNames(facts.v2._source ?? "");
|
|
40142
|
+
for (const fn of rust.functions) {
|
|
40143
|
+
if (!fn.isPublic) continue;
|
|
40144
|
+
if (API_CONVENTION_NAMES.has(fn.name)) continue;
|
|
40145
|
+
if (fn.inTestConfig) continue;
|
|
40146
|
+
if (referenced.has(fn.name)) continue;
|
|
40147
|
+
issues.push({
|
|
40148
|
+
ruleId: "rust/unused-pub-fn",
|
|
40149
|
+
category: "logic",
|
|
40150
|
+
severity: "low",
|
|
40151
|
+
aiSpecific: true,
|
|
40152
|
+
message: `Public function '${fn.name}' is not referenced anywhere in the file`,
|
|
40153
|
+
line: fn.line,
|
|
40154
|
+
column: fn.column,
|
|
40155
|
+
advice: `Remove the function or call it somewhere. Rust's compiler doesn't warn on pub fns missing consumers unless \`#![warn(dead_code)]\` is set at the crate root. AI agents that iterate on a file often leave these behind \u2014 the most common AI-rotation signature for Rust after unused-imports.`
|
|
40156
|
+
});
|
|
40157
|
+
}
|
|
40158
|
+
return issues;
|
|
40159
|
+
}
|
|
40160
|
+
});
|
|
40161
|
+
}
|
|
40162
|
+
});
|
|
40163
|
+
|
|
40164
|
+
// src/rules/rust/unwrap-in-production.ts
|
|
40165
|
+
function collectUnwrapIssues(node, testScopes, issues) {
|
|
40166
|
+
if (node.type === "call_expression") {
|
|
40167
|
+
const fn = node.childForFieldName("function");
|
|
40168
|
+
if (fn && fn.type === "field_expression") {
|
|
40169
|
+
const field = fn.childForFieldName("field");
|
|
40170
|
+
if (field && field.type === "field_identifier" && UNWRAP_METHODS.has(field.text)) {
|
|
40171
|
+
if (!isInsideTestFunction2(node, testScopes)) {
|
|
40172
|
+
issues.push({
|
|
40173
|
+
ruleId: "rust/unwrap-in-production",
|
|
40174
|
+
category: "logic",
|
|
40175
|
+
severity: "medium",
|
|
40176
|
+
aiSpecific: true,
|
|
40177
|
+
message: `'.${field.text}()' called in production code \u2014 panic risk on Err/None`,
|
|
40178
|
+
line: node.startPosition.row + 1,
|
|
40179
|
+
column: node.startPosition.column,
|
|
40180
|
+
advice: `Replace with '?' (early-return on Err), '.map_err(...)' for conversion, or an explicit 'match'. '.${field.text}()' is fine in tests \u2014 wrap with '#[cfg(test)]' or move into a '#[cfg(test)] mod tests' block to suppress.`
|
|
40181
|
+
});
|
|
40182
|
+
}
|
|
40183
|
+
}
|
|
40184
|
+
}
|
|
40185
|
+
}
|
|
40186
|
+
for (let i = 0; i < node.namedChildCount; i++) {
|
|
40187
|
+
const child = node.namedChild(i);
|
|
40188
|
+
if (child) collectUnwrapIssues(child, testScopes, issues);
|
|
40189
|
+
}
|
|
40190
|
+
}
|
|
40191
|
+
function isInsideTestFunction2(node, testScopes) {
|
|
40192
|
+
for (let p = node.parent; p; p = p.parent) {
|
|
40193
|
+
if (p.type === "function_item") {
|
|
40194
|
+
const nameField = p.childForFieldName("name");
|
|
40195
|
+
const name = nameField?.text;
|
|
40196
|
+
if (name && testScopes.has(name)) return true;
|
|
40197
|
+
if (p.text.startsWith("#[test]") || p.text.startsWith("#[cfg(test)]")) return true;
|
|
40198
|
+
return false;
|
|
40199
|
+
}
|
|
40200
|
+
if (p.type === "source_file") return false;
|
|
40201
|
+
}
|
|
40202
|
+
return false;
|
|
40203
|
+
}
|
|
40204
|
+
var UNWRAP_METHODS, rustUnwrapInProductionRule;
|
|
40205
|
+
var init_unwrap_in_production = __esm({
|
|
40206
|
+
"src/rules/rust/unwrap-in-production.ts"() {
|
|
40207
|
+
"use strict";
|
|
40208
|
+
init_rule();
|
|
40209
|
+
init_parser_rust();
|
|
40210
|
+
UNWRAP_METHODS = /* @__PURE__ */ new Set(["unwrap", "expect", "unwrap_or_else"]);
|
|
40211
|
+
rustUnwrapInProductionRule = createRule({
|
|
40212
|
+
id: "rust/unwrap-in-production",
|
|
40213
|
+
category: "logic",
|
|
40214
|
+
severity: "medium",
|
|
40215
|
+
aiSpecific: true,
|
|
40216
|
+
description: ".unwrap() / .expect() called outside of #[cfg(test)] / #[test] scope",
|
|
40217
|
+
create(_context) {
|
|
40218
|
+
return {};
|
|
40219
|
+
},
|
|
40220
|
+
analyze(_context, facts) {
|
|
40221
|
+
const issues = [];
|
|
40222
|
+
if (!facts.v2?.rustFile) return issues;
|
|
40223
|
+
const source = facts.v2._source ?? "";
|
|
40224
|
+
if (!source) return issues;
|
|
40225
|
+
const tree = parseRust(source);
|
|
40226
|
+
if (!tree) return issues;
|
|
40227
|
+
const testScopes = /* @__PURE__ */ new Set();
|
|
40228
|
+
for (const fn of facts.v2.rustFile.functions) {
|
|
40229
|
+
if (fn.inTestConfig && fn.name) testScopes.add(fn.name);
|
|
40230
|
+
}
|
|
40231
|
+
collectUnwrapIssues(tree.rootNode, testScopes, issues);
|
|
40232
|
+
return issues;
|
|
40233
|
+
}
|
|
40234
|
+
});
|
|
40235
|
+
}
|
|
40236
|
+
});
|
|
40237
|
+
|
|
39337
40238
|
// src/rules/security/dangerous-cors.ts
|
|
39338
40239
|
function scanForWildcardCors(source) {
|
|
39339
40240
|
const hits = [];
|
|
@@ -40924,6 +41825,251 @@ var init_weak_assertion = __esm({
|
|
|
40924
41825
|
}
|
|
40925
41826
|
});
|
|
40926
41827
|
|
|
41828
|
+
// src/rules/ts/enum-vs-as-const.ts
|
|
41829
|
+
var ENUM_DECL_REGEX, tsEnumVsAsConstRule;
|
|
41830
|
+
var init_enum_vs_as_const = __esm({
|
|
41831
|
+
"src/rules/ts/enum-vs-as-const.ts"() {
|
|
41832
|
+
"use strict";
|
|
41833
|
+
init_rule();
|
|
41834
|
+
ENUM_DECL_REGEX = /^[ \t]*(?:export\s+)?(?:const\s+)?enum\s+[A-Z_][A-Za-z0-9_]*\s*\{/gm;
|
|
41835
|
+
tsEnumVsAsConstRule = createRule({
|
|
41836
|
+
id: "ts/enum-vs-as-const",
|
|
41837
|
+
category: "typo",
|
|
41838
|
+
severity: "low",
|
|
41839
|
+
aiSpecific: true,
|
|
41840
|
+
description: "Uses `enum` \u2014 modern TS prefers `as const` objects",
|
|
41841
|
+
create(_context) {
|
|
41842
|
+
return {};
|
|
41843
|
+
},
|
|
41844
|
+
analyze(_context, facts) {
|
|
41845
|
+
const issues = [];
|
|
41846
|
+
const source = facts.v2?._source;
|
|
41847
|
+
if (!source) return issues;
|
|
41848
|
+
let match;
|
|
41849
|
+
ENUM_DECL_REGEX.lastIndex = 0;
|
|
41850
|
+
while ((match = ENUM_DECL_REGEX.exec(source)) !== null) {
|
|
41851
|
+
const line = source.slice(0, match.index).split("\n").length;
|
|
41852
|
+
issues.push({
|
|
41853
|
+
ruleId: "ts/enum-vs-as-const",
|
|
41854
|
+
category: "typo",
|
|
41855
|
+
severity: "low",
|
|
41856
|
+
aiSpecific: true,
|
|
41857
|
+
message: `'enum' is an AI / older-TS pattern \u2014 prefer 'as const' for a frozen object literal`,
|
|
41858
|
+
line,
|
|
41859
|
+
column: match[0].indexOf("enum") + 1,
|
|
41860
|
+
advice: 'Replace `enum Foo { A, B }` with `const Foo = { A: "A", B: "B" } as const` (or `const Foo = ["A", "B"] as const`). Modern TS style guides (Google, TS-eslint) prefer `as const` because enums have surprising runtime semantics. Reference: ts/enum-vs-as-const v0.19.'
|
|
41861
|
+
});
|
|
41862
|
+
}
|
|
41863
|
+
return issues;
|
|
41864
|
+
}
|
|
41865
|
+
});
|
|
41866
|
+
}
|
|
41867
|
+
});
|
|
41868
|
+
|
|
41869
|
+
// src/rules/ts/excessive-type-assertion.ts
|
|
41870
|
+
var DEFAULT_MAX, FN_DECL_REGEX, AS_REGEX, tsExcessiveTypeAssertionRule;
|
|
41871
|
+
var init_excessive_type_assertion = __esm({
|
|
41872
|
+
"src/rules/ts/excessive-type-assertion.ts"() {
|
|
41873
|
+
"use strict";
|
|
41874
|
+
init_rule();
|
|
41875
|
+
DEFAULT_MAX = 3;
|
|
41876
|
+
FN_DECL_REGEX = /^[ \t]*(?:export\s+)?(?:async\s+)?function\s+[A-Za-z_$][\w$]*\s*\([^)]*\)\s*[^{]*\{|^\s*(?:export\s+)?(?:const|let|var)\s+[A-Za-z_$][\w$]*\s*=\s*(?:async\s+)?\([^)]*\)\s*(?::\s*[^=]+)?\s*=>\s*\{|^\s*(?:public|private|protected|static|async|abstract|readonly|\s)*\s*[A-Za-z_$][\w$]*\s*\([^)]*\)\s*:\s*[^{]*\{/gm;
|
|
41877
|
+
AS_REGEX = /(?<![\w$])as\s+(?!const)([A-Z][\w$.,<>\[\]|&]*)/g;
|
|
41878
|
+
tsExcessiveTypeAssertionRule = createRule({
|
|
41879
|
+
id: "ts/excessive-type-assertion",
|
|
41880
|
+
category: "typo",
|
|
41881
|
+
severity: "low",
|
|
41882
|
+
aiSpecific: true,
|
|
41883
|
+
description: "Function with >3 `as` type assertions \u2014 likely AI fighting the type system",
|
|
41884
|
+
create(_context) {
|
|
41885
|
+
return { maxAssertionsPerFunction: DEFAULT_MAX };
|
|
41886
|
+
},
|
|
41887
|
+
analyze(context, facts) {
|
|
41888
|
+
const issues = [];
|
|
41889
|
+
const source = facts.v2?._source;
|
|
41890
|
+
if (!source) return issues;
|
|
41891
|
+
let match;
|
|
41892
|
+
FN_DECL_REGEX.lastIndex = 0;
|
|
41893
|
+
while ((match = FN_DECL_REGEX.exec(source)) !== null) {
|
|
41894
|
+
const startIdx = match.index;
|
|
41895
|
+
const openBraceIdx = source.indexOf("{", startIdx);
|
|
41896
|
+
if (openBraceIdx < 0) continue;
|
|
41897
|
+
let depth = 1;
|
|
41898
|
+
let i = openBraceIdx + 1;
|
|
41899
|
+
while (i < source.length && depth > 0) {
|
|
41900
|
+
const ch = source[i];
|
|
41901
|
+
if (ch === "{") depth++;
|
|
41902
|
+
else if (ch === "}") depth--;
|
|
41903
|
+
i++;
|
|
41904
|
+
}
|
|
41905
|
+
const body = source.slice(openBraceIdx, i);
|
|
41906
|
+
const line = source.slice(0, startIdx).split("\n").length;
|
|
41907
|
+
let asCount = 0;
|
|
41908
|
+
const seen = /* @__PURE__ */ new Set();
|
|
41909
|
+
let asMatch;
|
|
41910
|
+
AS_REGEX.lastIndex = 0;
|
|
41911
|
+
while ((asMatch = AS_REGEX.exec(body)) !== null) {
|
|
41912
|
+
const captured = asMatch[1];
|
|
41913
|
+
if (seen.has(captured)) continue;
|
|
41914
|
+
seen.add(captured);
|
|
41915
|
+
asCount++;
|
|
41916
|
+
}
|
|
41917
|
+
if (asCount > context.maxAssertionsPerFunction) {
|
|
41918
|
+
issues.push({
|
|
41919
|
+
ruleId: "ts/excessive-type-assertion",
|
|
41920
|
+
category: "typo",
|
|
41921
|
+
severity: "low",
|
|
41922
|
+
aiSpecific: true,
|
|
41923
|
+
message: `Function has ${asCount} 'as' assertions (max ${context.maxAssertionsPerFunction}) \u2014 likely AI fighting the type system`,
|
|
41924
|
+
line,
|
|
41925
|
+
column: 1,
|
|
41926
|
+
advice: "More than 3 `as` assertions in a function is a strong signal that the type is wrong, not the code. Fix the type definition (or use a type guard) instead of bypassing the type system. Reference: ts/excessive-type-assertion v0.19."
|
|
41927
|
+
});
|
|
41928
|
+
}
|
|
41929
|
+
}
|
|
41930
|
+
return issues;
|
|
41931
|
+
}
|
|
41932
|
+
});
|
|
41933
|
+
}
|
|
41934
|
+
});
|
|
41935
|
+
|
|
41936
|
+
// src/rules/ts/import-type-misuse.ts
|
|
41937
|
+
var INLINE_TYPE_IMPORT_REGEX, tsImportTypeMisuseRule;
|
|
41938
|
+
var init_import_type_misuse = __esm({
|
|
41939
|
+
"src/rules/ts/import-type-misuse.ts"() {
|
|
41940
|
+
"use strict";
|
|
41941
|
+
init_rule();
|
|
41942
|
+
INLINE_TYPE_IMPORT_REGEX = /^[ \t]*import\s*\{[^}]*\btype\s+[A-Za-z_]/gm;
|
|
41943
|
+
tsImportTypeMisuseRule = createRule({
|
|
41944
|
+
id: "ts/import-type-misuse",
|
|
41945
|
+
category: "typo",
|
|
41946
|
+
severity: "low",
|
|
41947
|
+
aiSpecific: true,
|
|
41948
|
+
description: "Inline `import { type X }` \u2014 prefer `import type { X }` for clarity",
|
|
41949
|
+
create(_context) {
|
|
41950
|
+
return {};
|
|
41951
|
+
},
|
|
41952
|
+
analyze(_context, facts) {
|
|
41953
|
+
const issues = [];
|
|
41954
|
+
const source = facts.v2?._source;
|
|
41955
|
+
if (!source) return issues;
|
|
41956
|
+
let match;
|
|
41957
|
+
INLINE_TYPE_IMPORT_REGEX.lastIndex = 0;
|
|
41958
|
+
while ((match = INLINE_TYPE_IMPORT_REGEX.exec(source)) !== null) {
|
|
41959
|
+
const line = source.slice(0, match.index).split("\n").length;
|
|
41960
|
+
issues.push({
|
|
41961
|
+
ruleId: "ts/import-type-misuse",
|
|
41962
|
+
category: "typo",
|
|
41963
|
+
severity: "low",
|
|
41964
|
+
aiSpecific: true,
|
|
41965
|
+
message: "Inline `type` in a value import \u2014 split into a separate `import type` statement",
|
|
41966
|
+
line,
|
|
41967
|
+
column: match[0].indexOf("type") + 1,
|
|
41968
|
+
advice: 'Use `import type { X } from "..."` instead of `import { type X } from "..."`. The inline form is valid but the split form is more common in real codebases and makes the type-only intent unambiguous. Reference: ts/import-type-misuse v0.19.'
|
|
41969
|
+
});
|
|
41970
|
+
}
|
|
41971
|
+
return issues;
|
|
41972
|
+
}
|
|
41973
|
+
});
|
|
41974
|
+
}
|
|
41975
|
+
});
|
|
41976
|
+
|
|
41977
|
+
// src/rules/ts/never-vs-unknown.ts
|
|
41978
|
+
var NEVER_RETURN_REGEX, THROW_OR_LOOP_REGEX, tsNeverVsUnknownRule;
|
|
41979
|
+
var init_never_vs_unknown = __esm({
|
|
41980
|
+
"src/rules/ts/never-vs-unknown.ts"() {
|
|
41981
|
+
"use strict";
|
|
41982
|
+
init_rule();
|
|
41983
|
+
NEVER_RETURN_REGEX = /^[ \t]*(?:export\s+)?(?:async\s+)?function\s+([A-Za-z_$][\w$]*)[^{]*:\s*(?:Promise<)?never\b[^{]*\{/gm;
|
|
41984
|
+
THROW_OR_LOOP_REGEX = /\b(?:throw\b|while\s*\(|for\s*\(|process\.exit\b|System\.exit\b)/;
|
|
41985
|
+
tsNeverVsUnknownRule = createRule({
|
|
41986
|
+
id: "ts/never-vs-unknown",
|
|
41987
|
+
category: "typo",
|
|
41988
|
+
severity: "low",
|
|
41989
|
+
aiSpecific: true,
|
|
41990
|
+
description: "Return type `: never` but body has no throw / loop / exit \u2014 likely AI misuse",
|
|
41991
|
+
create(_context) {
|
|
41992
|
+
return {};
|
|
41993
|
+
},
|
|
41994
|
+
analyze(_context, facts) {
|
|
41995
|
+
const issues = [];
|
|
41996
|
+
const source = facts.v2?._source;
|
|
41997
|
+
if (!source) return issues;
|
|
41998
|
+
let match;
|
|
41999
|
+
NEVER_RETURN_REGEX.lastIndex = 0;
|
|
42000
|
+
while ((match = NEVER_RETURN_REGEX.exec(source)) !== null) {
|
|
42001
|
+
const fnName = match[1];
|
|
42002
|
+
const startIdx = match.index;
|
|
42003
|
+
const line = source.slice(0, startIdx).split("\n").length;
|
|
42004
|
+
const openBraceIdx = source.indexOf("{", startIdx);
|
|
42005
|
+
if (openBraceIdx < 0) continue;
|
|
42006
|
+
let depth = 1;
|
|
42007
|
+
let i = openBraceIdx + 1;
|
|
42008
|
+
while (i < source.length && depth > 0) {
|
|
42009
|
+
const ch = source[i];
|
|
42010
|
+
if (ch === "{") depth++;
|
|
42011
|
+
else if (ch === "}") depth--;
|
|
42012
|
+
i++;
|
|
42013
|
+
}
|
|
42014
|
+
const body = source.slice(openBraceIdx, i);
|
|
42015
|
+
if (THROW_OR_LOOP_REGEX.test(body)) continue;
|
|
42016
|
+
issues.push({
|
|
42017
|
+
ruleId: "ts/never-vs-unknown",
|
|
42018
|
+
category: "typo",
|
|
42019
|
+
severity: "low",
|
|
42020
|
+
aiSpecific: true,
|
|
42021
|
+
message: `Function '${fnName}' returns 'never' but its body has no throw, loop, or exit \u2014 likely AI misuse`,
|
|
42022
|
+
line,
|
|
42023
|
+
column: match[0].indexOf("never") + 1,
|
|
42024
|
+
advice: 'The `never` return type means "this function never returns". Reserve it for functions that always throw, always loop, or always exit. For "impossible" branches, use a concrete type (`void`, `Error`, `unknown`) and an exhaustive check. Reference: ts/never-vs-unknown v0.19.'
|
|
42025
|
+
});
|
|
42026
|
+
}
|
|
42027
|
+
return issues;
|
|
42028
|
+
}
|
|
42029
|
+
});
|
|
42030
|
+
}
|
|
42031
|
+
});
|
|
42032
|
+
|
|
42033
|
+
// src/rules/ts/optional-chain-overuse.ts
|
|
42034
|
+
var DEFAULT_MIN_CHAIN_LENGTH, tsOptionalChainOveruseRule;
|
|
42035
|
+
var init_optional_chain_overuse = __esm({
|
|
42036
|
+
"src/rules/ts/optional-chain-overuse.ts"() {
|
|
42037
|
+
"use strict";
|
|
42038
|
+
init_rule();
|
|
42039
|
+
DEFAULT_MIN_CHAIN_LENGTH = 5;
|
|
42040
|
+
tsOptionalChainOveruseRule = createRule({
|
|
42041
|
+
id: "ts/optional-chain-overuse",
|
|
42042
|
+
category: "logic",
|
|
42043
|
+
severity: "low",
|
|
42044
|
+
aiSpecific: true,
|
|
42045
|
+
description: "Optional chaining (?.) used 5+ times in a single chain \u2014 AI tends to chain rather than narrow",
|
|
42046
|
+
create(_context) {
|
|
42047
|
+
return { minChainLength: DEFAULT_MIN_CHAIN_LENGTH };
|
|
42048
|
+
},
|
|
42049
|
+
analyze(context, facts) {
|
|
42050
|
+
const issues = [];
|
|
42051
|
+
const expressions = facts.v2.logic?.logicalExpressions;
|
|
42052
|
+
if (!expressions) return issues;
|
|
42053
|
+
for (const expression of expressions) {
|
|
42054
|
+
if (expression.depth >= context.minChainLength && expression.isOptionalChainLike) {
|
|
42055
|
+
issues.push({
|
|
42056
|
+
ruleId: "ts/optional-chain-overuse",
|
|
42057
|
+
category: "logic",
|
|
42058
|
+
severity: "low",
|
|
42059
|
+
aiSpecific: true,
|
|
42060
|
+
message: `Optional chain depth ${expression.depth} \u2014 break with an intermediate variable or guard clause`,
|
|
42061
|
+
line: expression.line,
|
|
42062
|
+
column: expression.column,
|
|
42063
|
+
advice: "Long optional chains are an AI pattern. Use a guard clause (`if (!value) return`) or intermediate variables to make the narrowing explicit. Reference: ts/optional-chain-overuse v0.19."
|
|
42064
|
+
});
|
|
42065
|
+
}
|
|
42066
|
+
}
|
|
42067
|
+
return issues;
|
|
42068
|
+
}
|
|
42069
|
+
});
|
|
42070
|
+
}
|
|
42071
|
+
});
|
|
42072
|
+
|
|
40927
42073
|
// src/rules/typo/calc-fontsize.ts
|
|
40928
42074
|
var FONT_SIZE_RE, calcFontsizeRule;
|
|
40929
42075
|
var init_calc_fontsize = __esm({
|
|
@@ -42028,7 +43174,7 @@ function spanEnd(node) {
|
|
|
42028
43174
|
}
|
|
42029
43175
|
return void 0;
|
|
42030
43176
|
}
|
|
42031
|
-
function
|
|
43177
|
+
function buildLineOffsets2(source) {
|
|
42032
43178
|
const offsets = [0];
|
|
42033
43179
|
let byteOffset = 0;
|
|
42034
43180
|
for (let i = 0; i < source.length; i++) {
|
|
@@ -44029,9 +45175,60 @@ function buildV2Facts(facts, source, ext, framework, config, templateClassNames
|
|
|
44029
45175
|
})),
|
|
44030
45176
|
disabledRules: extractDisabledRules(source),
|
|
44031
45177
|
templateClassNames,
|
|
45178
|
+
// v0.18.9 — populate the Rust AST record when the file is `.rs`.
|
|
45179
|
+
// Calling `parseRustFile` here keeps the dead-code detector's
|
|
45180
|
+
// import-binding pass a pure function over the same source the
|
|
45181
|
+
// walker saw. The native-binding guard lives inside
|
|
45182
|
+
// `parseRustFile` (returns an empty record when tree-sitter is
|
|
45183
|
+
// unavailable).
|
|
45184
|
+
rustFile: buildRustFileRecord(facts.filePath, source),
|
|
44032
45185
|
_source: source
|
|
44033
45186
|
};
|
|
44034
45187
|
}
|
|
45188
|
+
function buildRustFileRecord(filePath, source) {
|
|
45189
|
+
if (!filePath.toLowerCase().endsWith(".rs")) return void 0;
|
|
45190
|
+
const structure = parseRustFile(filePath, source);
|
|
45191
|
+
return {
|
|
45192
|
+
imports: structure.imports.map((i) => ({
|
|
45193
|
+
path: i.path,
|
|
45194
|
+
names: i.names.map((n) => ({ name: n.name, ...n.alias ? { alias: n.alias } : {} })),
|
|
45195
|
+
isGlob: i.isGlob,
|
|
45196
|
+
line: i.line,
|
|
45197
|
+
column: i.column
|
|
45198
|
+
})),
|
|
45199
|
+
functions: structure.functions.map((f) => ({
|
|
45200
|
+
name: f.name,
|
|
45201
|
+
line: f.line,
|
|
45202
|
+
column: f.column,
|
|
45203
|
+
isPublic: f.isPublic,
|
|
45204
|
+
isMethod: f.isMethod,
|
|
45205
|
+
...f.receiver ? { receiver: f.receiver } : {},
|
|
45206
|
+
bodyLines: f.bodyLines,
|
|
45207
|
+
inTestConfig: f.inTestConfig
|
|
45208
|
+
})),
|
|
45209
|
+
structs: structure.structs.map((s) => ({
|
|
45210
|
+
name: s.name,
|
|
45211
|
+
line: s.line,
|
|
45212
|
+
column: s.column,
|
|
45213
|
+
isPublic: s.isPublic,
|
|
45214
|
+
isDerive: s.isDerive,
|
|
45215
|
+
derives: [...s.derives]
|
|
45216
|
+
})),
|
|
45217
|
+
traits: structure.traits.map((t) => ({
|
|
45218
|
+
name: t.name,
|
|
45219
|
+
line: t.line,
|
|
45220
|
+
column: t.column,
|
|
45221
|
+
isPublic: t.isPublic
|
|
45222
|
+
})),
|
|
45223
|
+
impls: structure.impls.map((ip) => ({
|
|
45224
|
+
...ip.trait ? { trait: ip.trait } : {},
|
|
45225
|
+
type: ip.type,
|
|
45226
|
+
methods: [...ip.methods],
|
|
45227
|
+
line: ip.line,
|
|
45228
|
+
column: ip.column
|
|
45229
|
+
}))
|
|
45230
|
+
};
|
|
45231
|
+
}
|
|
44035
45232
|
function splitFilePath(filePath) {
|
|
44036
45233
|
const baseName2 = filePath.split("/").pop() ?? filePath;
|
|
44037
45234
|
const dotIdx = baseName2.lastIndexOf(".");
|
|
@@ -44046,6 +45243,7 @@ var init_v2_build = __esm({
|
|
|
44046
45243
|
"src/engine/visitors/v2-build.ts"() {
|
|
44047
45244
|
"use strict";
|
|
44048
45245
|
init_scan_helpers();
|
|
45246
|
+
init_rust();
|
|
44049
45247
|
TAILWIND_COLOR_RE = /^(?:bg|text|border|ring|from|to|via|fill|stroke)-([a-z]+-\d+|white|black|transparent|current|\[.+?\])$/;
|
|
44050
45248
|
TAILWIND_SPACING_RE = /^(?:[pm][xytrbl]?|gap|space-[xy])-(\d+(?:\.\d+)?)$/;
|
|
44051
45249
|
TAILWIND_RADIUS_RE = /^(?:rounded(?:-[a-z]+)?)-(.+)$/;
|
|
@@ -44078,7 +45276,7 @@ function mergeTemplateClassNames(filePath, source, facts, templateClassNames) {
|
|
|
44078
45276
|
}
|
|
44079
45277
|
}
|
|
44080
45278
|
function extractFacts(filePath, ast, source, supportsRsc = true, framework = "react", config) {
|
|
44081
|
-
const lineOffsets =
|
|
45279
|
+
const lineOffsets = buildLineOffsets2(source);
|
|
44082
45280
|
const isTypeScript = /\.tsx?$/i.test(filePath);
|
|
44083
45281
|
const NON_JSX_FRAMEWORKS = /* @__PURE__ */ new Set(["vue", "svelte", "astro"]);
|
|
44084
45282
|
const facts = {
|
|
@@ -44366,7 +45564,7 @@ var init_naturalness_anomaly = __esm({
|
|
|
44366
45564
|
const issues = [];
|
|
44367
45565
|
const source = facts.v2?._source;
|
|
44368
45566
|
if (!source) return issues;
|
|
44369
|
-
const lineOffsets =
|
|
45567
|
+
const lineOffsets = buildLineOffsets2(source);
|
|
44370
45568
|
const components = facts.v2?.components ?? [];
|
|
44371
45569
|
const perComponentMetrics = components.filter((c) => c.loc > 0).map(
|
|
44372
45570
|
(c) => computeNaturalnessForRange(source, lineOffsets, c.line, c.line + c.loc - 1, context.model)
|
|
@@ -45013,6 +46211,10 @@ var init_builtins = __esm({
|
|
|
45013
46211
|
init_expired_code_example();
|
|
45014
46212
|
init_stale_function_reference();
|
|
45015
46213
|
init_stale_package_reference();
|
|
46214
|
+
init_identical_block();
|
|
46215
|
+
init_error_wrap_without_context();
|
|
46216
|
+
init_nil_slice_vs_empty();
|
|
46217
|
+
init_struct_tag_inconsistency();
|
|
45016
46218
|
init_gap_monopoly();
|
|
45017
46219
|
init_math_element_uniformity();
|
|
45018
46220
|
init_math_grid_uniformity();
|
|
@@ -45022,7 +46224,6 @@ var init_builtins = __esm({
|
|
|
45022
46224
|
init_ghost_defensive();
|
|
45023
46225
|
init_heaps_deviation();
|
|
45024
46226
|
init_key_prop_missing();
|
|
45025
|
-
init_ks_distribution_shift();
|
|
45026
46227
|
init_math_any_density();
|
|
45027
46228
|
init_math_console_log_storm();
|
|
45028
46229
|
init_math_gini_class_usage();
|
|
@@ -45037,6 +46238,10 @@ var init_builtins = __esm({
|
|
|
45037
46238
|
init_halstead_anomaly();
|
|
45038
46239
|
init_terminology_drift();
|
|
45039
46240
|
init_ux_pattern_fragmentation();
|
|
46241
|
+
init_stringly_typed();
|
|
46242
|
+
init_todo_macro();
|
|
46243
|
+
init_unused_pub_fn();
|
|
46244
|
+
init_unwrap_in_production();
|
|
45040
46245
|
init_dangerous_cors();
|
|
45041
46246
|
init_eval();
|
|
45042
46247
|
init_exposed_env_var();
|
|
@@ -45052,6 +46257,11 @@ var init_builtins = __esm({
|
|
|
45052
46257
|
init_fake_placeholder();
|
|
45053
46258
|
init_missing_edge_case();
|
|
45054
46259
|
init_weak_assertion();
|
|
46260
|
+
init_enum_vs_as_const();
|
|
46261
|
+
init_excessive_type_assertion();
|
|
46262
|
+
init_import_type_misuse();
|
|
46263
|
+
init_never_vs_unknown();
|
|
46264
|
+
init_optional_chain_overuse();
|
|
45055
46265
|
init_calc_fontsize();
|
|
45056
46266
|
init_calc_raw_px();
|
|
45057
46267
|
init_clamp_offscale();
|
|
@@ -45114,6 +46324,10 @@ var init_builtins = __esm({
|
|
|
45114
46324
|
expiredCodeExampleRule,
|
|
45115
46325
|
staleFunctionReferenceRule,
|
|
45116
46326
|
stalePackageReferenceRule,
|
|
46327
|
+
dupIdenticalBlockRule,
|
|
46328
|
+
goErrorWrapWithoutContextRule,
|
|
46329
|
+
goNilSliceVsEmptyRule,
|
|
46330
|
+
goStructTagInconsistencyRule,
|
|
45117
46331
|
gapMonopolyRule,
|
|
45118
46332
|
mathElementUniformityRule,
|
|
45119
46333
|
mathGridUniformityRule,
|
|
@@ -45123,7 +46337,6 @@ var init_builtins = __esm({
|
|
|
45123
46337
|
ghostDefensiveRule,
|
|
45124
46338
|
heapsDeviationRule,
|
|
45125
46339
|
keyPropMissingRule,
|
|
45126
|
-
ksDistributionShiftRule,
|
|
45127
46340
|
mathAnyDensityRule,
|
|
45128
46341
|
mathConsoleLogStormRule,
|
|
45129
46342
|
mathGiniClassUsageRule,
|
|
@@ -45138,6 +46351,10 @@ var init_builtins = __esm({
|
|
|
45138
46351
|
halsteadAnomalyRule,
|
|
45139
46352
|
terminologyDriftRule,
|
|
45140
46353
|
uxPatternFragmentationRule,
|
|
46354
|
+
rustStringlyTypedRule,
|
|
46355
|
+
rustTodoMacroRule,
|
|
46356
|
+
rustUnusedPubFnRule,
|
|
46357
|
+
rustUnwrapInProductionRule,
|
|
45141
46358
|
dangerousCorsRule,
|
|
45142
46359
|
evalRule,
|
|
45143
46360
|
exposedEnvVarRule,
|
|
@@ -45153,6 +46370,11 @@ var init_builtins = __esm({
|
|
|
45153
46370
|
fakePlaceholderRule,
|
|
45154
46371
|
missingEdgeCaseRule,
|
|
45155
46372
|
weakAssertionRule,
|
|
46373
|
+
tsEnumVsAsConstRule,
|
|
46374
|
+
tsExcessiveTypeAssertionRule,
|
|
46375
|
+
tsImportTypeMisuseRule,
|
|
46376
|
+
tsNeverVsUnknownRule,
|
|
46377
|
+
tsOptionalChainOveruseRule,
|
|
45156
46378
|
calcFontsizeRule,
|
|
45157
46379
|
calcRawPxRule,
|
|
45158
46380
|
clampOffscaleRule,
|
|
@@ -47118,6 +48340,22 @@ var init_registry = __esm({
|
|
|
47118
48340
|
if (!filter) return list;
|
|
47119
48341
|
return list.filter((r) => filter.kind === "ai" ? r.aiSpecific : !r.aiSpecific);
|
|
47120
48342
|
}
|
|
48343
|
+
/** v0.18.8: remove every rule where `predicate(rule)` returns true.
|
|
48344
|
+
* Used by focused calibration scripts to scan a single category
|
|
48345
|
+
* without instantiating all 99 rules. */
|
|
48346
|
+
removeWhere(predicate) {
|
|
48347
|
+
let removed = 0;
|
|
48348
|
+
for (const [id, rule] of this.rules) {
|
|
48349
|
+
if (predicate(rule)) {
|
|
48350
|
+
this.rules.delete(id);
|
|
48351
|
+
removed++;
|
|
48352
|
+
}
|
|
48353
|
+
}
|
|
48354
|
+
return removed;
|
|
48355
|
+
}
|
|
48356
|
+
all() {
|
|
48357
|
+
return Array.from(this.rules.values());
|
|
48358
|
+
}
|
|
47121
48359
|
createContexts(config, filePath, cwd, hotspotIssues = []) {
|
|
47122
48360
|
const context = {
|
|
47123
48361
|
config,
|
|
@@ -47143,1044 +48381,1943 @@ var signal_strength_default;
|
|
|
47143
48381
|
var init_signal_strength = __esm({
|
|
47144
48382
|
"src/rules/signal-strength.json"() {
|
|
47145
48383
|
signal_strength_default = {
|
|
47146
|
-
"
|
|
47147
|
-
recall:
|
|
47148
|
-
fpRate:
|
|
47149
|
-
ratio:
|
|
47150
|
-
precision: 0.
|
|
47151
|
-
lastCalibratedAt: "2026-
|
|
48384
|
+
"ai/any-density": {
|
|
48385
|
+
recall: 6e-3,
|
|
48386
|
+
fpRate: 37e-4,
|
|
48387
|
+
ratio: 175.31,
|
|
48388
|
+
precision: 0.6523,
|
|
48389
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
47152
48390
|
verdict: "USEFUL",
|
|
47153
|
-
_calibrationNote: "
|
|
47154
|
-
aiSpecific: true
|
|
48391
|
+
_calibrationNote: "v8.5 calibration (v0.18.9, 2026-07-01): v7+v8 combined corpus (252080 neg + 294178 pos). v8.5 TP=1760, FP=938, P=65.2%, FPR=0.37%, lift=175.31. v7 was USEFUL (TP=1313, FP=758, lift=153.41). v8 was USEFUL (TP=447, FP=180).",
|
|
48392
|
+
aiSpecific: true,
|
|
48393
|
+
_v7Verdict: "USEFUL",
|
|
48394
|
+
_v7Lift: 153.41,
|
|
48395
|
+
_v7Recall: 55e-4,
|
|
48396
|
+
_v7FpRate: 41e-4,
|
|
48397
|
+
_v7Precision: 0.634,
|
|
48398
|
+
_v8Verdict: "USEFUL",
|
|
48399
|
+
_v8Lift: 271.97
|
|
47155
48400
|
},
|
|
47156
|
-
"
|
|
47157
|
-
recall:
|
|
47158
|
-
fpRate:
|
|
47159
|
-
ratio:
|
|
47160
|
-
precision: 0.
|
|
47161
|
-
lastCalibratedAt: "2026-
|
|
47162
|
-
verdict: "
|
|
47163
|
-
_calibrationNote: "
|
|
47164
|
-
|
|
47165
|
-
|
|
48401
|
+
"ai/comment-ratio": {
|
|
48402
|
+
recall: 0.2771,
|
|
48403
|
+
fpRate: 0.1578,
|
|
48404
|
+
ratio: 4.26,
|
|
48405
|
+
precision: 0.6721,
|
|
48406
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
48407
|
+
verdict: "USEFUL",
|
|
48408
|
+
_calibrationNote: "v8.5 calibration (v0.18.9, 2026-07-01): v7+v8 combined corpus (252080 neg + 294178 pos). v8.5 TP=81513, FP=39766, P=67.2%, FPR=15.78%, lift=4.26. v7 was USEFUL (TP=60308, FP=29876, lift=4.11). v8 was USEFUL (TP=21205, FP=9890).",
|
|
48409
|
+
aiSpecific: true,
|
|
48410
|
+
_v7Verdict: "USEFUL",
|
|
48411
|
+
_v7Lift: 4.11,
|
|
48412
|
+
_v7Recall: 0.2545,
|
|
48413
|
+
_v7FpRate: 0.1629,
|
|
48414
|
+
_v7Precision: 0.6687,
|
|
48415
|
+
_v8Verdict: "USEFUL",
|
|
48416
|
+
_v8Lift: 4.73
|
|
47166
48417
|
},
|
|
47167
|
-
"
|
|
47168
|
-
recall: 0.
|
|
47169
|
-
fpRate: 0.
|
|
47170
|
-
ratio:
|
|
47171
|
-
precision: 0.
|
|
47172
|
-
lastCalibratedAt: "2026-
|
|
47173
|
-
verdict: "
|
|
47174
|
-
_calibrationNote: "
|
|
47175
|
-
aiSpecific:
|
|
48418
|
+
"ai/compression-profile": {
|
|
48419
|
+
recall: 0.3478,
|
|
48420
|
+
fpRate: 0.1488,
|
|
48421
|
+
ratio: 4.92,
|
|
48422
|
+
precision: 0.7318,
|
|
48423
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
48424
|
+
verdict: "USEFUL",
|
|
48425
|
+
_calibrationNote: "v8.5 calibration (v0.18.9, 2026-07-01): v7+v8 combined corpus (252080 neg + 294178 pos). v8.5 TP=102328, FP=37511, P=73.2%, FPR=14.88%, lift=4.92. v7 was USEFUL (TP=75031, FP=27473, lift=4.89). v8 was USEFUL (TP=27297, FP=10038).",
|
|
48426
|
+
aiSpecific: true,
|
|
48427
|
+
_v7Verdict: "USEFUL",
|
|
48428
|
+
_v7Lift: 4.89,
|
|
48429
|
+
_v7Recall: 0.3166,
|
|
48430
|
+
_v7FpRate: 0.1498,
|
|
48431
|
+
_v7Precision: 0.732,
|
|
48432
|
+
_v8Verdict: "USEFUL",
|
|
48433
|
+
_v8Lift: 5
|
|
47176
48434
|
},
|
|
47177
|
-
"
|
|
47178
|
-
recall:
|
|
48435
|
+
"ai/console-debug-storm": {
|
|
48436
|
+
recall: 73e-4,
|
|
47179
48437
|
fpRate: 9e-4,
|
|
47180
|
-
ratio:
|
|
47181
|
-
precision: 0.
|
|
47182
|
-
lastCalibratedAt: "2026-
|
|
48438
|
+
ratio: 949.21,
|
|
48439
|
+
precision: 0.9,
|
|
48440
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
47183
48441
|
verdict: "USEFUL",
|
|
47184
|
-
_calibrationNote: "
|
|
47185
|
-
aiSpecific: true
|
|
48442
|
+
_calibrationNote: "v8.5 calibration (v0.18.9, 2026-07-01): v7+v8 combined corpus (252080 neg + 294178 pos). v8.5 TP=2150, FP=239, P=90.0%, FPR=0.09%, lift=949.21. v7 was USEFUL (TP=1912, FP=175, lift=960.19). v8 was USEFUL (TP=238, FP=64).",
|
|
48443
|
+
aiSpecific: true,
|
|
48444
|
+
_v7Verdict: "USEFUL",
|
|
48445
|
+
_v7Lift: 960.19,
|
|
48446
|
+
_v7Recall: 81e-4,
|
|
48447
|
+
_v7FpRate: 1e-3,
|
|
48448
|
+
_v7Precision: 0.9161,
|
|
48449
|
+
_v8Verdict: "USEFUL",
|
|
48450
|
+
_v8Lift: 845.55
|
|
47186
48451
|
},
|
|
47187
|
-
"
|
|
47188
|
-
recall:
|
|
47189
|
-
fpRate:
|
|
47190
|
-
ratio:
|
|
47191
|
-
precision: 0.
|
|
47192
|
-
lastCalibratedAt: "2026-
|
|
48452
|
+
"ai/default-react-stack": {
|
|
48453
|
+
recall: 1e-3,
|
|
48454
|
+
fpRate: 0,
|
|
48455
|
+
ratio: 251225.49,
|
|
48456
|
+
precision: 0.9966,
|
|
48457
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
47193
48458
|
verdict: "USEFUL",
|
|
47194
|
-
_calibrationNote: "
|
|
47195
|
-
aiSpecific: true
|
|
48459
|
+
_calibrationNote: "v8.5 calibration (v0.18.9, 2026-07-01): v7+v8 combined corpus (252080 neg + 294178 pos). v8.5 TP=294, FP=1, P=99.7%, FPR=0.00%, lift=251225.49. v7 was USEFUL (TP=231, FP=1, lift=182622.43). v8 was USEFUL (TP=63, FP=0). v0.19 default-on (explicit defaultOff: false): P 99.7% / 251k lift \u2014 core AI fingerprint.",
|
|
48460
|
+
aiSpecific: true,
|
|
48461
|
+
_v7Verdict: "USEFUL",
|
|
48462
|
+
_v7Lift: 182622.43,
|
|
48463
|
+
_v7Recall: 1e-3,
|
|
48464
|
+
_v7FpRate: 0,
|
|
48465
|
+
_v7Precision: 0.9957,
|
|
48466
|
+
_v8Verdict: "USEFUL",
|
|
48467
|
+
_v8Lift: 99999,
|
|
48468
|
+
defaultOff: false
|
|
47196
48469
|
},
|
|
47197
|
-
"
|
|
47198
|
-
recall:
|
|
47199
|
-
fpRate: 0,
|
|
47200
|
-
ratio:
|
|
47201
|
-
precision: 0.
|
|
47202
|
-
lastCalibratedAt: "2026-
|
|
48470
|
+
"ai/errors-near-eof": {
|
|
48471
|
+
recall: 0.0948,
|
|
48472
|
+
fpRate: 0.052,
|
|
48473
|
+
ratio: 13.09,
|
|
48474
|
+
precision: 0.6803,
|
|
48475
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
47203
48476
|
verdict: "USEFUL",
|
|
47204
|
-
_calibrationNote: "
|
|
47205
|
-
aiSpecific: true
|
|
48477
|
+
_calibrationNote: "v8.5 calibration (v0.18.9, 2026-07-01): v7+v8 combined corpus (252080 neg + 294178 pos). v8.5 TP=27874, FP=13097, P=68.0%, FPR=5.20%, lift=13.09. v7 was USEFUL (TP=16673, FP=10112, lift=11.29). v8 was USEFUL (TP=11201, FP=2985).",
|
|
48478
|
+
aiSpecific: true,
|
|
48479
|
+
_v7Verdict: "USEFUL",
|
|
48480
|
+
_v7Lift: 11.29,
|
|
48481
|
+
_v7Recall: 0.0704,
|
|
48482
|
+
_v7FpRate: 0.0551,
|
|
48483
|
+
_v7Precision: 0.6225,
|
|
48484
|
+
_v8Verdict: "USEFUL",
|
|
48485
|
+
_v8Lift: 18.16
|
|
47206
48486
|
},
|
|
47207
|
-
"
|
|
47208
|
-
recall:
|
|
48487
|
+
"ai/fetch-default-overuse": {
|
|
48488
|
+
recall: 27e-4,
|
|
47209
48489
|
fpRate: 3e-4,
|
|
47210
|
-
ratio:
|
|
47211
|
-
precision: 0.
|
|
47212
|
-
lastCalibratedAt: "2026-
|
|
48490
|
+
ratio: 2679.84,
|
|
48491
|
+
precision: 0.9036,
|
|
48492
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
47213
48493
|
verdict: "USEFUL",
|
|
47214
|
-
_calibrationNote: "
|
|
47215
|
-
aiSpecific: true
|
|
48494
|
+
_calibrationNote: "v8.5 calibration (v0.18.9, 2026-07-01): v7+v8 combined corpus (252080 neg + 294178 pos). v8.5 TP=797, FP=85, P=90.4%, FPR=0.03%, lift=2679.84. v7 was USEFUL (TP=666, FP=76, lift=2166.14). v8 was USEFUL (TP=131, FP=9).",
|
|
48495
|
+
aiSpecific: true,
|
|
48496
|
+
_v7Verdict: "USEFUL",
|
|
48497
|
+
_v7Lift: 2166.14,
|
|
48498
|
+
_v7Recall: 28e-4,
|
|
48499
|
+
_v7FpRate: 4e-4,
|
|
48500
|
+
_v7Precision: 0.8976,
|
|
48501
|
+
_v8Verdict: "USEFUL",
|
|
48502
|
+
_v8Lift: 7139.19
|
|
47216
48503
|
},
|
|
47217
|
-
"
|
|
47218
|
-
recall:
|
|
48504
|
+
"ai/library-reinvention": {
|
|
48505
|
+
recall: 3e-4,
|
|
47219
48506
|
fpRate: 0,
|
|
47220
|
-
ratio:
|
|
47221
|
-
precision: 0.
|
|
47222
|
-
lastCalibratedAt: "2026-
|
|
47223
|
-
verdict: "USEFUL",
|
|
47224
|
-
_calibrationNote: "v7 corpus re-calibration (2026-06-27, min-date=2025-01-01): 184488 neg + 239054 pos. USEFUL \u2014 TP=58, FP=5, P=92.1%, FPR=0.00%, lift=9.0. aiSpecific=True.",
|
|
47225
|
-
aiSpecific: true
|
|
47226
|
-
},
|
|
47227
|
-
"visual/math-default-font": {
|
|
47228
|
-
recall: 13e-4,
|
|
47229
|
-
fpRate: 4e-4,
|
|
47230
|
-
ratio: 3.4,
|
|
47231
|
-
precision: 0.8151,
|
|
47232
|
-
lastCalibratedAt: "2026-06-27T12:00:00Z",
|
|
48507
|
+
ratio: 47415.05,
|
|
48508
|
+
precision: 0.9405,
|
|
48509
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
47233
48510
|
verdict: "USEFUL",
|
|
47234
|
-
_calibrationNote: "
|
|
47235
|
-
aiSpecific: true
|
|
48511
|
+
_calibrationNote: "v8.5 calibration (v0.18.9, 2026-07-01): v7+v8 combined corpus (252080 neg + 294178 pos). v8.5 TP=79, FP=5, P=94.0%, FPR=0.00%, lift=47415.05. v7 was USEFUL (TP=64, FP=5, lift=34024.44). v8 was USEFUL (TP=15, FP=0).",
|
|
48512
|
+
aiSpecific: true,
|
|
48513
|
+
_v7Verdict: "USEFUL",
|
|
48514
|
+
_v7Lift: 34024.44,
|
|
48515
|
+
_v7Recall: 3e-4,
|
|
48516
|
+
_v7FpRate: 0,
|
|
48517
|
+
_v7Precision: 0.9275,
|
|
48518
|
+
_v8Verdict: "USEFUL",
|
|
48519
|
+
_v8Lift: 99999
|
|
47236
48520
|
},
|
|
47237
|
-
"
|
|
48521
|
+
"ai/log-rank-histogram": {
|
|
47238
48522
|
recall: 0,
|
|
47239
48523
|
fpRate: 0,
|
|
47240
48524
|
ratio: 0,
|
|
47241
48525
|
precision: 0,
|
|
47242
|
-
lastCalibratedAt: "2026-
|
|
48526
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
47243
48527
|
verdict: "DORMANT",
|
|
47244
|
-
|
|
47245
|
-
|
|
47246
|
-
|
|
48528
|
+
_calibrationNote: "v8.5 calibration (v0.18.9, 2026-07-01): rule did not fire on v8.5 corpus (252080 neg + 294178 pos = 546258 files). Preserved v7 data. v7 verdict=OK, v7 lift=0, v7 recall=0, v7 FPR=0, v7 precision=0.",
|
|
48529
|
+
aiSpecific: true,
|
|
48530
|
+
_v7Verdict: "OK",
|
|
48531
|
+
_v7Lift: 0,
|
|
48532
|
+
_v7Recall: 0,
|
|
48533
|
+
_v7FpRate: 0,
|
|
48534
|
+
_v7Precision: 0,
|
|
48535
|
+
_v8Verdict: "DORMANT",
|
|
48536
|
+
_v8Lift: 1,
|
|
48537
|
+
defaultOff: true
|
|
47247
48538
|
},
|
|
47248
|
-
"
|
|
47249
|
-
recall:
|
|
47250
|
-
fpRate:
|
|
47251
|
-
ratio:
|
|
47252
|
-
precision: 0.
|
|
47253
|
-
lastCalibratedAt: "2026-
|
|
47254
|
-
verdict: "
|
|
47255
|
-
_calibrationNote: "
|
|
47256
|
-
aiSpecific: true
|
|
48539
|
+
"ai/markdown-leakage": {
|
|
48540
|
+
recall: 0,
|
|
48541
|
+
fpRate: 0,
|
|
48542
|
+
ratio: 10003.17,
|
|
48543
|
+
precision: 0.3571,
|
|
48544
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
48545
|
+
verdict: "OK",
|
|
48546
|
+
_calibrationNote: "v8.5 calibration (v0.18.9, 2026-07-01): v7+v8 combined corpus (252080 neg + 294178 pos). v8.5 TP=5, FP=9, P=35.7%, FPR=0.00%, lift=10003.17. v7 was USEFUL (TP=5, FP=2, lift=65504.64). v8 was INVERTED (TP=0, FP=7).",
|
|
48547
|
+
aiSpecific: true,
|
|
48548
|
+
_v7Verdict: "USEFUL",
|
|
48549
|
+
_v7Lift: 65504.64,
|
|
48550
|
+
_v7Recall: 0,
|
|
48551
|
+
_v7FpRate: 0,
|
|
48552
|
+
_v7Precision: 0.7143,
|
|
48553
|
+
_v8Verdict: "INVERTED",
|
|
48554
|
+
_v8Lift: 0
|
|
47257
48555
|
},
|
|
47258
|
-
"
|
|
47259
|
-
recall:
|
|
47260
|
-
fpRate:
|
|
47261
|
-
ratio:
|
|
47262
|
-
precision: 0.
|
|
47263
|
-
lastCalibratedAt: "2026-
|
|
48556
|
+
"ai/renyi-profile": {
|
|
48557
|
+
recall: 0,
|
|
48558
|
+
fpRate: 0,
|
|
48559
|
+
ratio: 5251.67,
|
|
48560
|
+
precision: 0.25,
|
|
48561
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
48562
|
+
verdict: "OK",
|
|
48563
|
+
_calibrationNote: "v8.5 calibration (v0.18.9, 2026-07-01): v7+v8 combined corpus (252080 neg + 294178 pos). v8.5 TP=4, FP=12, P=25.0%, FPR=0.00%, lift=5251.67. v7 was OK (TP=3, FP=9, lift=5094.81). v8 was OK (TP=1, FP=3).",
|
|
48564
|
+
aiSpecific: true,
|
|
48565
|
+
_v7Verdict: "OK",
|
|
48566
|
+
_v7Lift: 5094.81,
|
|
48567
|
+
_v7Recall: 0,
|
|
48568
|
+
_v7FpRate: 0,
|
|
48569
|
+
_v7Precision: 0.25,
|
|
48570
|
+
_v8Verdict: "OK",
|
|
48571
|
+
_v8Lift: 5722.25
|
|
48572
|
+
},
|
|
48573
|
+
"ai/segment-surprisal-cv": {
|
|
48574
|
+
recall: 0.2019,
|
|
48575
|
+
fpRate: 0.0787,
|
|
48576
|
+
ratio: 9.52,
|
|
48577
|
+
precision: 0.7495,
|
|
48578
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
47264
48579
|
verdict: "USEFUL",
|
|
47265
|
-
_calibrationNote: "
|
|
47266
|
-
aiSpecific: true
|
|
48580
|
+
_calibrationNote: "v8.5 calibration (v0.18.9, 2026-07-01): v7+v8 combined corpus (252080 neg + 294178 pos). v8.5 TP=59390, FP=19849, P=75.0%, FPR=7.87%, lift=9.52. v7 was USEFUL (TP=43498, FP=14983, lift=9.11). v8 was USEFUL (TP=15892, FP=4866).",
|
|
48581
|
+
aiSpecific: true,
|
|
48582
|
+
_v7Verdict: "USEFUL",
|
|
48583
|
+
_v7Lift: 9.11,
|
|
48584
|
+
_v7Recall: 0.1836,
|
|
48585
|
+
_v7FpRate: 0.0817,
|
|
48586
|
+
_v7Precision: 0.7438,
|
|
48587
|
+
_v8Verdict: "USEFUL",
|
|
48588
|
+
_v8Lift: 10.8
|
|
47267
48589
|
},
|
|
47268
|
-
"
|
|
47269
|
-
recall:
|
|
48590
|
+
"ai/state-default-overuse": {
|
|
48591
|
+
recall: 3e-3,
|
|
47270
48592
|
fpRate: 6e-4,
|
|
47271
|
-
ratio:
|
|
47272
|
-
precision: 0.
|
|
47273
|
-
lastCalibratedAt: "2026-
|
|
48593
|
+
ratio: 1315.06,
|
|
48594
|
+
precision: 0.8451,
|
|
48595
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
47274
48596
|
verdict: "USEFUL",
|
|
47275
|
-
_calibrationNote: "
|
|
47276
|
-
aiSpecific: true
|
|
48597
|
+
_calibrationNote: "v8.5 calibration (v0.18.9, 2026-07-01): v7+v8 combined corpus (252080 neg + 294178 pos). v8.5 TP=884, FP=162, P=84.5%, FPR=0.06%, lift=1315.06. v7 was USEFUL (TP=701, FP=158, lift=947.32). v8 was USEFUL (TP=183, FP=4).",
|
|
48598
|
+
aiSpecific: true,
|
|
48599
|
+
_v7Verdict: "USEFUL",
|
|
48600
|
+
_v7Lift: 947.32,
|
|
48601
|
+
_v7Recall: 3e-3,
|
|
48602
|
+
_v7FpRate: 9e-4,
|
|
48603
|
+
_v7Precision: 0.8161,
|
|
48604
|
+
_v8Verdict: "USEFUL",
|
|
48605
|
+
_v8Lift: 16799.55
|
|
47277
48606
|
},
|
|
47278
|
-
"
|
|
48607
|
+
"ai/tailwind-color-overuse": {
|
|
48608
|
+
recall: 0.0264,
|
|
48609
|
+
fpRate: 38e-4,
|
|
48610
|
+
ratio: 230.97,
|
|
48611
|
+
precision: 0.8888,
|
|
48612
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
48613
|
+
verdict: "USEFUL",
|
|
48614
|
+
_calibrationNote: "v8.5 calibration (v0.18.9, 2026-07-01): v7+v8 combined corpus (252080 neg + 294178 pos). v8.5 TP=7752, FP=970, P=88.9%, FPR=0.38%, lift=230.97. v7 was USEFUL (TP=5169, FP=958, lift=161.52). v8 was USEFUL (TP=2583, FP=12).",
|
|
48615
|
+
aiSpecific: true,
|
|
48616
|
+
_v7Verdict: "USEFUL",
|
|
48617
|
+
_v7Lift: 161.52,
|
|
48618
|
+
_v7Recall: 0.0218,
|
|
48619
|
+
_v7FpRate: 52e-4,
|
|
48620
|
+
_v7Precision: 0.8436,
|
|
48621
|
+
_v8Verdict: "USEFUL",
|
|
48622
|
+
_v8Lift: 5695.79
|
|
48623
|
+
},
|
|
48624
|
+
"ai/text-like-ratio": {
|
|
48625
|
+
recall: 0,
|
|
48626
|
+
fpRate: 0,
|
|
48627
|
+
ratio: 201664,
|
|
48628
|
+
precision: 0.8,
|
|
48629
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
48630
|
+
verdict: "USEFUL",
|
|
48631
|
+
_calibrationNote: "v8.5 calibration (v0.18.9, 2026-07-01): v7+v8 combined corpus (252080 neg + 294178 pos). v8.5 TP=4, FP=1, P=80.0%, FPR=0.00%, lift=201664.00. v7 was USEFUL (TP=3, FP=1, lift=137559.75). v8 was USEFUL (TP=1, FP=0).",
|
|
48632
|
+
aiSpecific: true,
|
|
48633
|
+
_v7Verdict: "USEFUL",
|
|
48634
|
+
_v7Lift: 137559.75,
|
|
48635
|
+
_v7Recall: 0,
|
|
48636
|
+
_v7FpRate: 0,
|
|
48637
|
+
_v7Precision: 0.75,
|
|
48638
|
+
_v8Verdict: "USEFUL",
|
|
48639
|
+
_v8Lift: 99999
|
|
48640
|
+
},
|
|
48641
|
+
"ai/whitespace-regularity": {
|
|
48642
|
+
recall: 0.0733,
|
|
48643
|
+
fpRate: 0.0677,
|
|
48644
|
+
ratio: 8.25,
|
|
48645
|
+
precision: 0.5583,
|
|
48646
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
48647
|
+
verdict: "USEFUL",
|
|
48648
|
+
_calibrationNote: "v8.5 calibration (v0.18.9, 2026-07-01): v7+v8 combined corpus (252080 neg + 294178 pos). v8.5 TP=21567, FP=17061, P=55.8%, FPR=6.77%, lift=8.25. v7 was USEFUL (TP=17466, FP=13438, lift=7.71). v8 was USEFUL (TP=4101, FP=3623).",
|
|
48649
|
+
aiSpecific: true,
|
|
48650
|
+
_v7Verdict: "USEFUL",
|
|
48651
|
+
_v7Lift: 7.71,
|
|
48652
|
+
_v7Recall: 0.0737,
|
|
48653
|
+
_v7FpRate: 0.0733,
|
|
48654
|
+
_v7Precision: 0.5652,
|
|
48655
|
+
_v8Verdict: "USEFUL",
|
|
48656
|
+
_v8Lift: 10.06
|
|
48657
|
+
},
|
|
48658
|
+
"arch/astro-island-leak": {
|
|
47279
48659
|
recall: 0,
|
|
47280
48660
|
fpRate: 0,
|
|
47281
48661
|
ratio: 0,
|
|
47282
48662
|
precision: 0,
|
|
47283
|
-
lastCalibratedAt: "2026-
|
|
48663
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
47284
48664
|
verdict: "DORMANT",
|
|
47285
|
-
|
|
47286
|
-
|
|
47287
|
-
|
|
48665
|
+
_calibrationNote: "v8.5 calibration (v0.18.9, 2026-07-01): rule did not fire on v8.5 corpus (252080 neg + 294178 pos = 546258 files). Preserved v7 data. v7 verdict=DORMANT, v7 lift=0, v7 recall=0, v7 FPR=0, v7 precision=0.",
|
|
48666
|
+
aiSpecific: true,
|
|
48667
|
+
_v7Verdict: "DORMANT",
|
|
48668
|
+
_v7Lift: 0,
|
|
48669
|
+
_v7Recall: 0,
|
|
48670
|
+
_v7FpRate: 0,
|
|
48671
|
+
_v7Precision: 0,
|
|
48672
|
+
_v8Verdict: "DORMANT",
|
|
48673
|
+
_v8Lift: 1,
|
|
48674
|
+
defaultOff: true
|
|
47288
48675
|
},
|
|
47289
48676
|
"component/giant-component": {
|
|
47290
|
-
recall: 0.
|
|
47291
|
-
fpRate:
|
|
47292
|
-
ratio:
|
|
47293
|
-
precision: 0.
|
|
47294
|
-
lastCalibratedAt: "2026-
|
|
48677
|
+
recall: 0.0181,
|
|
48678
|
+
fpRate: 59e-4,
|
|
48679
|
+
ratio: 132.31,
|
|
48680
|
+
precision: 0.7815,
|
|
48681
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
47295
48682
|
verdict: "USEFUL",
|
|
47296
|
-
_calibrationNote: "
|
|
47297
|
-
aiSpecific: true
|
|
48683
|
+
_calibrationNote: "v8.5 calibration (v0.18.9, 2026-07-01): v7+v8 combined corpus (252080 neg + 294178 pos). v8.5 TP=5326, FP=1489, P=78.2%, FPR=0.59%, lift=132.31. v7 was USEFUL (TP=4205, FP=1413, lift=97.16). v8 was USEFUL (TP=1121, FP=76).",
|
|
48684
|
+
aiSpecific: true,
|
|
48685
|
+
_v7Verdict: "USEFUL",
|
|
48686
|
+
_v7Lift: 97.16,
|
|
48687
|
+
_v7Recall: 0.0177,
|
|
48688
|
+
_v7FpRate: 77e-4,
|
|
48689
|
+
_v7Precision: 0.7485,
|
|
48690
|
+
_v8Verdict: "USEFUL",
|
|
48691
|
+
_v8Lift: 846.15
|
|
48692
|
+
},
|
|
48693
|
+
"component/multiple-components-per-file": {
|
|
48694
|
+
recall: 0.0751,
|
|
48695
|
+
fpRate: 0.0423,
|
|
48696
|
+
ratio: 15.96,
|
|
48697
|
+
precision: 0.6747,
|
|
48698
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
48699
|
+
verdict: "USEFUL",
|
|
48700
|
+
_calibrationNote: "v8.5 calibration (v0.18.9, 2026-07-01): v7+v8 combined corpus (252080 neg + 294178 pos). v8.5 TP=22103, FP=10655, P=67.5%, FPR=4.23%, lift=15.96. v7 was USEFUL (TP=16288, FP=9589, lift=12.04). v8 was USEFUL (TP=5815, FP=1066).",
|
|
48701
|
+
aiSpecific: false,
|
|
48702
|
+
_v7Verdict: "USEFUL",
|
|
48703
|
+
_v7Lift: 12.04,
|
|
48704
|
+
_v7Recall: 0.0687,
|
|
48705
|
+
_v7FpRate: 0.0523,
|
|
48706
|
+
_v7Precision: 0.6294,
|
|
48707
|
+
_v8Verdict: "USEFUL",
|
|
48708
|
+
_v8Lift: 54.44
|
|
47298
48709
|
},
|
|
47299
48710
|
"component/shadcn-prop-mismatch": {
|
|
47300
|
-
recall:
|
|
48711
|
+
recall: 16e-4,
|
|
47301
48712
|
fpRate: 1e-4,
|
|
47302
|
-
ratio:
|
|
47303
|
-
precision: 0.
|
|
47304
|
-
lastCalibratedAt: "2026-
|
|
48713
|
+
ratio: 9990.98,
|
|
48714
|
+
precision: 0.9512,
|
|
48715
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
47305
48716
|
verdict: "USEFUL",
|
|
47306
|
-
_calibrationNote: "
|
|
47307
|
-
aiSpecific: true
|
|
48717
|
+
_calibrationNote: "v8.5 calibration (v0.18.9, 2026-07-01): v7+v8 combined corpus (252080 neg + 294178 pos). v8.5 TP=468, FP=24, P=95.1%, FPR=0.01%, lift=9990.98. v7 was USEFUL (TP=314, FP=24, lift=7099.57). v8 was USEFUL (TP=154, FP=0). v0.19 default-on (explicit defaultOff: false): P 95.1% / 9990x lift \u2014 UI bug.",
|
|
48718
|
+
aiSpecific: true,
|
|
48719
|
+
_v7Verdict: "USEFUL",
|
|
48720
|
+
_v7Lift: 7099.57,
|
|
48721
|
+
_v7Recall: 13e-4,
|
|
48722
|
+
_v7FpRate: 1e-4,
|
|
48723
|
+
_v7Precision: 0.929,
|
|
48724
|
+
_v8Verdict: "USEFUL",
|
|
48725
|
+
_v8Lift: 99999,
|
|
48726
|
+
defaultOff: false
|
|
47308
48727
|
},
|
|
47309
|
-
"
|
|
47310
|
-
recall:
|
|
47311
|
-
fpRate:
|
|
47312
|
-
ratio:
|
|
47313
|
-
precision: 0.
|
|
47314
|
-
lastCalibratedAt: "2026-
|
|
47315
|
-
verdict: "OK",
|
|
47316
|
-
_calibrationNote: "v7 corpus re-calibration (2026-06-27, min-date=2025-01-01): 184488 neg + 239054 pos. OK \u2014 TP=67, FP=30, P=69.1%, FPR=0.02%, lift=1.7. aiSpecific=True.",
|
|
47317
|
-
aiSpecific: true
|
|
47318
|
-
},
|
|
47319
|
-
"layout/math-element-uniformity": {
|
|
47320
|
-
recall: 28e-4,
|
|
47321
|
-
fpRate: 12e-4,
|
|
47322
|
-
ratio: 2.28,
|
|
47323
|
-
precision: 0.7475,
|
|
47324
|
-
lastCalibratedAt: "2026-06-27T12:00:00Z",
|
|
48728
|
+
"context/import-path-mismatch": {
|
|
48729
|
+
recall: 0.0681,
|
|
48730
|
+
fpRate: 0.0167,
|
|
48731
|
+
ratio: 49.48,
|
|
48732
|
+
precision: 0.8263,
|
|
48733
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
47325
48734
|
verdict: "USEFUL",
|
|
47326
|
-
_calibrationNote: "
|
|
47327
|
-
aiSpecific:
|
|
48735
|
+
_calibrationNote: "v8.5 calibration (v0.18.9, 2026-07-01): v7+v8 combined corpus (252080 neg + 294178 pos). v8.5 TP=20032, FP=4210, P=82.6%, FPR=1.67%, lift=49.48. v7 was USEFUL (TP=17672, FP=4202, lift=35.26). v8 was USEFUL (TP=2360, FP=8).",
|
|
48736
|
+
aiSpecific: false,
|
|
48737
|
+
_v7Verdict: "USEFUL",
|
|
48738
|
+
_v7Lift: 35.26,
|
|
48739
|
+
_v7Recall: 0.0746,
|
|
48740
|
+
_v7FpRate: 0.0229,
|
|
48741
|
+
_v7Precision: 0.8079,
|
|
48742
|
+
_v8Verdict: "USEFUL",
|
|
48743
|
+
_v8Lift: 8554.38
|
|
47328
48744
|
},
|
|
47329
|
-
"
|
|
47330
|
-
recall: 2e-4,
|
|
47331
|
-
fpRate: 1e-4,
|
|
47332
|
-
ratio: 1.36,
|
|
47333
|
-
precision: 0.6379,
|
|
47334
|
-
lastCalibratedAt: "2026-06-27T12:00:00Z",
|
|
47335
|
-
verdict: "HYGIENE",
|
|
47336
|
-
_calibrationNote: "v7 corpus re-calibration (2026-06-27, min-date=2025-01-01): 184488 neg + 239054 pos. HYGIENE \u2014 TP=37, FP=21, P=63.8%, FPR=0.01%, lift=1.4. aiSpecific=False.",
|
|
47337
|
-
aiSpecific: false
|
|
47338
|
-
},
|
|
47339
|
-
"perf/css-bloat": {
|
|
47340
|
-
recall: 0.0117,
|
|
47341
|
-
fpRate: 32e-4,
|
|
47342
|
-
ratio: 3.64,
|
|
47343
|
-
precision: 0.8252,
|
|
47344
|
-
lastCalibratedAt: "2026-06-27T12:00:00Z",
|
|
47345
|
-
verdict: "HYGIENE",
|
|
47346
|
-
_calibrationNote: "v7 corpus re-calibration (2026-06-27, min-date=2025-01-01): 184488 neg + 239054 pos. HYGIENE \u2014 TP=2790, FP=591, P=82.5%, FPR=0.32%, lift=3.6. aiSpecific=False.",
|
|
47347
|
-
aiSpecific: false
|
|
47348
|
-
},
|
|
47349
|
-
"wcag/focus-appearance": {
|
|
47350
|
-
recall: 26e-4,
|
|
47351
|
-
fpRate: 1e-4,
|
|
47352
|
-
ratio: 19.68,
|
|
47353
|
-
precision: 0.9623,
|
|
47354
|
-
lastCalibratedAt: "2026-06-27T12:00:00Z",
|
|
47355
|
-
verdict: "HYGIENE",
|
|
47356
|
-
_calibrationNote: "v7 corpus re-calibration (2026-06-27, min-date=2025-01-01): 184488 neg + 239054 pos. HYGIENE \u2014 TP=612, FP=24, P=96.2%, FPR=0.01%, lift=19.7. aiSpecific=False.",
|
|
47357
|
-
aiSpecific: false
|
|
47358
|
-
},
|
|
47359
|
-
"wcag/target-size": {
|
|
48745
|
+
"db/duplicate-index": {
|
|
47360
48746
|
recall: 0,
|
|
47361
48747
|
fpRate: 0,
|
|
47362
48748
|
ratio: 0,
|
|
47363
48749
|
precision: 0,
|
|
47364
|
-
lastCalibratedAt: "2026-
|
|
48750
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
47365
48751
|
verdict: "DORMANT",
|
|
47366
|
-
|
|
47367
|
-
|
|
47368
|
-
|
|
47369
|
-
|
|
47370
|
-
|
|
47371
|
-
|
|
47372
|
-
|
|
47373
|
-
|
|
47374
|
-
|
|
47375
|
-
|
|
47376
|
-
verdict: "HYGIENE",
|
|
47377
|
-
_calibrationNote: "v7 corpus re-calibration (2026-06-27, min-date=2025-01-01): 184488 neg + 239054 pos. HYGIENE \u2014 TP=16288, FP=9589, P=62.9%, FPR=5.20%, lift=1.3. aiSpecific=False.",
|
|
47378
|
-
aiSpecific: false
|
|
47379
|
-
},
|
|
47380
|
-
"context/import-path-mismatch": {
|
|
47381
|
-
recall: 0.0739,
|
|
47382
|
-
fpRate: 0.0228,
|
|
47383
|
-
ratio: 3.25,
|
|
47384
|
-
precision: 0.8079,
|
|
47385
|
-
lastCalibratedAt: "2026-06-27T12:00:00Z",
|
|
47386
|
-
verdict: "HYGIENE",
|
|
47387
|
-
_calibrationNote: "v7 corpus re-calibration (2026-06-27, min-date=2025-01-01): 184488 neg + 239054 pos. HYGIENE \u2014 TP=17672, FP=4202, P=80.8%, FPR=2.28%, lift=3.2. aiSpecific=False.",
|
|
47388
|
-
aiSpecific: false
|
|
47389
|
-
},
|
|
47390
|
-
"logic/key-prop-missing": {
|
|
47391
|
-
recall: 17e-4,
|
|
47392
|
-
fpRate: 14e-4,
|
|
47393
|
-
ratio: 1.28,
|
|
47394
|
-
precision: 0.6246,
|
|
47395
|
-
lastCalibratedAt: "2026-06-27T12:00:00Z",
|
|
47396
|
-
verdict: "HYGIENE",
|
|
47397
|
-
_calibrationNote: "v7 corpus re-calibration (2026-06-27, min-date=2025-01-01): 184488 neg + 239054 pos. HYGIENE \u2014 TP=416, FP=250, P=62.5%, FPR=0.14%, lift=1.3. aiSpecific=False.",
|
|
47398
|
-
aiSpecific: false
|
|
47399
|
-
},
|
|
47400
|
-
"logic/math-variable-name-entropy": {
|
|
47401
|
-
recall: 2e-4,
|
|
47402
|
-
fpRate: 1e-4,
|
|
47403
|
-
ratio: 1.07,
|
|
47404
|
-
precision: 0.5806,
|
|
47405
|
-
lastCalibratedAt: "2026-06-27T12:00:00Z",
|
|
47406
|
-
verdict: "HYGIENE",
|
|
47407
|
-
_calibrationNote: "v7 corpus re-calibration (2026-06-27, min-date=2025-01-01): 184488 neg + 239054 pos. HYGIENE \u2014 TP=36, FP=26, P=58.1%, FPR=0.01%, lift=1.1. aiSpecific=False.",
|
|
47408
|
-
aiSpecific: false
|
|
47409
|
-
},
|
|
47410
|
-
"security/public-admin-route": {
|
|
47411
|
-
recall: 28e-4,
|
|
47412
|
-
fpRate: 78e-4,
|
|
47413
|
-
ratio: 0.4,
|
|
47414
|
-
precision: 0.2251,
|
|
47415
|
-
lastCalibratedAt: "2026-06-26T22:30:00Z",
|
|
47416
|
-
verdict: "HYGIENE",
|
|
47417
|
-
_calibrationNote: "v4 corpus (2026-06-25): 95,599 neg + 76,550 pos (frontend, TS/TSX/JS/JSX). INVERTED \u2014 TP=217, FP=747, P=22.5%, FPR=0.78%, lift=0.4. [v0.12.2: reclassified to HYGIENE because rule is aiSpecific: false]",
|
|
47418
|
-
defaultOff: true,
|
|
47419
|
-
aiSpecific: false
|
|
47420
|
-
},
|
|
47421
|
-
"security/unsafe-html-render": {
|
|
47422
|
-
recall: 13e-4,
|
|
47423
|
-
fpRate: 9e-4,
|
|
47424
|
-
ratio: 1.5,
|
|
47425
|
-
precision: 0.661,
|
|
47426
|
-
lastCalibratedAt: "2026-06-27T12:00:00Z",
|
|
47427
|
-
verdict: "HYGIENE",
|
|
47428
|
-
_calibrationNote: "v7 corpus re-calibration (2026-06-27, min-date=2025-01-01): 184488 neg + 239054 pos. HYGIENE \u2014 TP=312, FP=160, P=66.1%, FPR=0.09%, lift=1.5. aiSpecific=False.",
|
|
47429
|
-
aiSpecific: false
|
|
47430
|
-
},
|
|
47431
|
-
"visual/naturalness-anomaly": {
|
|
47432
|
-
recall: 0.1645,
|
|
47433
|
-
fpRate: 0.0617,
|
|
47434
|
-
ratio: 2.67,
|
|
47435
|
-
precision: 0.7755,
|
|
47436
|
-
lastCalibratedAt: "2026-06-27T12:00:00Z",
|
|
47437
|
-
verdict: "USEFUL",
|
|
47438
|
-
_calibrationNote: "v7 corpus re-calibration (2026-06-27, min-date=2025-01-01): 184488 neg + 239054 pos. USEFUL \u2014 TP=39319, FP=11382, P=77.6%, FPR=6.17%, lift=2.7. aiSpecific=True.",
|
|
47439
|
-
aiSpecific: true
|
|
48752
|
+
_calibrationNote: "v8.5 calibration (v0.18.9, 2026-07-01): rule did not fire on v8.5 corpus (252080 neg + 294178 pos = 546258 files). Preserved v7 data. v7 verdict=DORMANT, v7 lift=0, v7 recall=0, v7 FPR=0, v7 precision=0.",
|
|
48753
|
+
aiSpecific: false,
|
|
48754
|
+
_v7Verdict: "DORMANT",
|
|
48755
|
+
_v7Lift: 0,
|
|
48756
|
+
_v7Recall: 0,
|
|
48757
|
+
_v7FpRate: 0,
|
|
48758
|
+
_v7Precision: 0,
|
|
48759
|
+
_v8Verdict: "DORMANT",
|
|
48760
|
+
_v8Lift: 1,
|
|
48761
|
+
defaultOff: true
|
|
47440
48762
|
},
|
|
47441
|
-
"
|
|
48763
|
+
"db/enum-sprawl": {
|
|
47442
48764
|
recall: 0,
|
|
47443
48765
|
fpRate: 0,
|
|
47444
|
-
ratio:
|
|
47445
|
-
precision: 0
|
|
47446
|
-
lastCalibratedAt: "2026-
|
|
47447
|
-
verdict: "
|
|
47448
|
-
_calibrationNote: "
|
|
47449
|
-
aiSpecific:
|
|
48766
|
+
ratio: 0,
|
|
48767
|
+
precision: 0,
|
|
48768
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
48769
|
+
verdict: "DORMANT",
|
|
48770
|
+
_calibrationNote: "v8.5 calibration (v0.18.9, 2026-07-01): rule did not fire on v8.5 corpus (252080 neg + 294178 pos = 546258 files). Preserved v7 data. v7 verdict=DORMANT, v7 lift=0, v7 recall=0, v7 FPR=0, v7 precision=0.",
|
|
48771
|
+
aiSpecific: false,
|
|
48772
|
+
_v7Verdict: "DORMANT",
|
|
48773
|
+
_v7Lift: 0,
|
|
48774
|
+
_v7Recall: 0,
|
|
48775
|
+
_v7FpRate: 0,
|
|
48776
|
+
_v7Precision: 0,
|
|
48777
|
+
_v8Verdict: "DORMANT",
|
|
48778
|
+
_v8Lift: 1,
|
|
48779
|
+
defaultOff: true
|
|
47450
48780
|
},
|
|
47451
|
-
"
|
|
48781
|
+
"db/missing-fk-index": {
|
|
47452
48782
|
recall: 0,
|
|
47453
48783
|
fpRate: 0,
|
|
47454
48784
|
ratio: 0,
|
|
47455
48785
|
precision: 0,
|
|
47456
|
-
lastCalibratedAt: "2026-
|
|
48786
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
47457
48787
|
verdict: "DORMANT",
|
|
47458
|
-
|
|
47459
|
-
|
|
47460
|
-
|
|
48788
|
+
_calibrationNote: "v8.5 calibration (v0.18.9, 2026-07-01): rule did not fire on v8.5 corpus (252080 neg + 294178 pos = 546258 files). Preserved v7 data. v7 verdict=DORMANT, v7 lift=0, v7 recall=0, v7 FPR=0, v7 precision=0.",
|
|
48789
|
+
aiSpecific: false,
|
|
48790
|
+
_v7Verdict: "DORMANT",
|
|
48791
|
+
_v7Lift: 0,
|
|
48792
|
+
_v7Recall: 0,
|
|
48793
|
+
_v7FpRate: 0,
|
|
48794
|
+
_v7Precision: 0,
|
|
48795
|
+
_v8Verdict: "DORMANT",
|
|
48796
|
+
_v8Lift: 1,
|
|
48797
|
+
defaultOff: true
|
|
47461
48798
|
},
|
|
47462
|
-
"
|
|
48799
|
+
"db/missing-not-null": {
|
|
47463
48800
|
recall: 0,
|
|
47464
48801
|
fpRate: 0,
|
|
47465
48802
|
ratio: 0,
|
|
47466
48803
|
precision: 0,
|
|
47467
|
-
lastCalibratedAt: "2026-
|
|
48804
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
47468
48805
|
verdict: "DORMANT",
|
|
47469
|
-
|
|
47470
|
-
|
|
47471
|
-
|
|
48806
|
+
_calibrationNote: "v8.5 calibration (v0.18.9, 2026-07-01): rule did not fire on v8.5 corpus (252080 neg + 294178 pos = 546258 files). Preserved v7 data. v7 verdict=DORMANT, v7 lift=0, v7 recall=0, v7 FPR=0, v7 precision=0.",
|
|
48807
|
+
aiSpecific: false,
|
|
48808
|
+
_v7Verdict: "DORMANT",
|
|
48809
|
+
_v7Lift: 0,
|
|
48810
|
+
_v7Recall: 0,
|
|
48811
|
+
_v7FpRate: 0,
|
|
48812
|
+
_v7Precision: 0,
|
|
48813
|
+
_v8Verdict: "DORMANT",
|
|
48814
|
+
_v8Lift: 1,
|
|
48815
|
+
defaultOff: true
|
|
47472
48816
|
},
|
|
47473
|
-
"
|
|
48817
|
+
"db/naming-inconsistency": {
|
|
47474
48818
|
recall: 0,
|
|
47475
48819
|
fpRate: 0,
|
|
47476
48820
|
ratio: 0,
|
|
47477
48821
|
precision: 0,
|
|
47478
|
-
lastCalibratedAt: "2026-
|
|
48822
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
47479
48823
|
verdict: "DORMANT",
|
|
47480
|
-
|
|
47481
|
-
|
|
47482
|
-
|
|
48824
|
+
_calibrationNote: "v8.5 calibration (v0.18.9, 2026-07-01): rule did not fire on v8.5 corpus (252080 neg + 294178 pos = 546258 files). Preserved v7 data. v7 verdict=DORMANT, v7 lift=0, v7 recall=0, v7 FPR=0, v7 precision=0.",
|
|
48825
|
+
aiSpecific: false,
|
|
48826
|
+
_v7Verdict: "DORMANT",
|
|
48827
|
+
_v7Lift: 0,
|
|
48828
|
+
_v7Recall: 0,
|
|
48829
|
+
_v7FpRate: 0,
|
|
48830
|
+
_v7Precision: 0,
|
|
48831
|
+
_v8Verdict: "DORMANT",
|
|
48832
|
+
_v8Lift: 1,
|
|
48833
|
+
defaultOff: true
|
|
47483
48834
|
},
|
|
47484
|
-
"
|
|
48835
|
+
"db/sql-concat": {
|
|
48836
|
+
recall: 5e-4,
|
|
48837
|
+
fpRate: 1e-4,
|
|
48838
|
+
ratio: 7511.26,
|
|
48839
|
+
precision: 0.8343,
|
|
48840
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
48841
|
+
verdict: "USEFUL",
|
|
48842
|
+
_calibrationNote: "v8.5 calibration (v0.18.9, 2026-07-01): v7+v8 combined corpus (252080 neg + 294178 pos). v8.5 TP=141, FP=28, P=83.4%, FPR=0.01%, lift=7511.26. v7 was DORMANT (TP=0, FP=0, lift=1.00). v8 was USEFUL (TP=141, FP=28).",
|
|
48843
|
+
aiSpecific: true,
|
|
48844
|
+
_v7Verdict: "DORMANT",
|
|
48845
|
+
_v7Lift: 1,
|
|
48846
|
+
_v7Recall: 0,
|
|
48847
|
+
_v7FpRate: 0,
|
|
48848
|
+
_v7Precision: 0,
|
|
48849
|
+
_v8Verdict: "USEFUL",
|
|
48850
|
+
_v8Lift: 2046.08
|
|
48851
|
+
},
|
|
48852
|
+
"dead/dead-branch": {
|
|
48853
|
+
recall: 2e-4,
|
|
48854
|
+
fpRate: 4e-4,
|
|
48855
|
+
ratio: 1080.68,
|
|
48856
|
+
precision: 0.4244,
|
|
48857
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
48858
|
+
verdict: "OK",
|
|
48859
|
+
_calibrationNote: "v8.5 (v0.18.9): v85 verdict=OK, v7 was DORMANT, v8 was OK. v0.18.8 v8a first measurement (1000 files): see docs/research/v0.18.8-dead-rules-measurement.md.",
|
|
48860
|
+
aiSpecific: true,
|
|
48861
|
+
_v7Verdict: "DORMANT",
|
|
48862
|
+
_v7Lift: 1,
|
|
48863
|
+
_v7Recall: 0,
|
|
48864
|
+
_v7FpRate: 0,
|
|
48865
|
+
_v7Precision: 0,
|
|
48866
|
+
_v8Verdict: "OK",
|
|
48867
|
+
_v8Lift: 294.38
|
|
48868
|
+
},
|
|
48869
|
+
"dead/unreachable": {
|
|
48870
|
+
recall: 1e-4,
|
|
48871
|
+
fpRate: 6e-4,
|
|
48872
|
+
ratio: 153.14,
|
|
48873
|
+
precision: 0.0966,
|
|
48874
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
48875
|
+
verdict: "OK",
|
|
48876
|
+
_calibrationNote: "v8.5 (v0.18.9): v85 verdict=OK, v7 was DORMANT, v8 was OK. v0.18.8 v8a first measurement (1000 files): see docs/research/v0.18.8-dead-rules-measurement.md.",
|
|
48877
|
+
aiSpecific: true,
|
|
48878
|
+
_v7Verdict: "DORMANT",
|
|
48879
|
+
_v7Lift: 1,
|
|
48880
|
+
_v7Recall: 0,
|
|
48881
|
+
_v7FpRate: 0,
|
|
48882
|
+
_v7Precision: 0,
|
|
48883
|
+
_v8Verdict: "OK",
|
|
48884
|
+
_v8Lift: 41.71
|
|
48885
|
+
},
|
|
48886
|
+
"dead/unused-import": {
|
|
48887
|
+
recall: 0.0379,
|
|
48888
|
+
fpRate: 0.0222,
|
|
48889
|
+
ratio: 30.06,
|
|
48890
|
+
precision: 0.6662,
|
|
48891
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
48892
|
+
verdict: "USEFUL",
|
|
48893
|
+
_calibrationNote: "v8.5 (v0.18.9): v85 verdict=USEFUL, v7 was DORMANT, v8 was USEFUL. v0.18.8 v8a first measurement (1000 files): see docs/research/v0.18.8-dead-rules-measurement.md.",
|
|
48894
|
+
aiSpecific: true,
|
|
48895
|
+
_v7Verdict: "DORMANT",
|
|
48896
|
+
_v7Lift: 1,
|
|
48897
|
+
_v7Recall: 0,
|
|
48898
|
+
_v7FpRate: 0,
|
|
48899
|
+
_v7Precision: 0,
|
|
48900
|
+
_v8Verdict: "USEFUL",
|
|
48901
|
+
_v8Lift: 8.19
|
|
48902
|
+
},
|
|
48903
|
+
"dead/unused-local": {
|
|
48904
|
+
recall: 0.0477,
|
|
48905
|
+
fpRate: 74e-4,
|
|
48906
|
+
ratio: 120.18,
|
|
48907
|
+
precision: 0.8834,
|
|
48908
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
48909
|
+
verdict: "USEFUL",
|
|
48910
|
+
_calibrationNote: "v8.5 (v0.18.9): v85 verdict=USEFUL, v7 was DORMANT, v8 was USEFUL. v0.18.8 v8a first measurement (1000 files): see docs/research/v0.18.8-dead-rules-measurement.md. v0.19 default-on (explicit defaultOff: false): P 88.3% / FPR 0.74% / 120x lift \u2014 code hygiene.",
|
|
48911
|
+
aiSpecific: true,
|
|
48912
|
+
_v7Verdict: "DORMANT",
|
|
48913
|
+
_v7Lift: 1,
|
|
48914
|
+
_v7Recall: 0,
|
|
48915
|
+
_v7FpRate: 0,
|
|
48916
|
+
_v7Precision: 0,
|
|
48917
|
+
_v8Verdict: "USEFUL",
|
|
48918
|
+
_v8Lift: 32.74,
|
|
48919
|
+
defaultOff: false
|
|
48920
|
+
},
|
|
48921
|
+
"dead/unused-parameter": {
|
|
48922
|
+
recall: 8e-4,
|
|
48923
|
+
fpRate: 27e-4,
|
|
48924
|
+
ratio: 98,
|
|
48925
|
+
precision: 0.2628,
|
|
48926
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
48927
|
+
verdict: "OK",
|
|
48928
|
+
_calibrationNote: "v8.5 (v0.18.9): v85 verdict=OK, v7 was DORMANT, v8 was OK. v0.18.8 v8a first measurement (1000 files): see docs/research/v0.18.8-dead-rules-measurement.md.",
|
|
48929
|
+
aiSpecific: true,
|
|
48930
|
+
_v7Verdict: "DORMANT",
|
|
48931
|
+
_v7Lift: 1,
|
|
48932
|
+
_v7Recall: 0,
|
|
48933
|
+
_v7FpRate: 0,
|
|
48934
|
+
_v7Precision: 0,
|
|
48935
|
+
_v8Verdict: "OK",
|
|
48936
|
+
_v8Lift: 26.7
|
|
48937
|
+
},
|
|
48938
|
+
"docs/broken-link": {
|
|
48939
|
+
recall: 14e-4,
|
|
48940
|
+
fpRate: 23e-4,
|
|
48941
|
+
ratio: 178.13,
|
|
48942
|
+
precision: 0.4155,
|
|
48943
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
48944
|
+
verdict: "OK",
|
|
48945
|
+
_calibrationNote: "v8.5 calibration (v0.18.9, 2026-07-01): v7+v8 combined corpus (252080 neg + 294178 pos). v8.5 TP=418, FP=588, P=41.6%, FPR=0.23%, lift=178.13. v7 was DORMANT (TP=0, FP=0, lift=1.00). v8 was OK (TP=418, FP=588).",
|
|
48946
|
+
aiSpecific: false,
|
|
48947
|
+
_v7Verdict: "DORMANT",
|
|
48948
|
+
_v7Lift: 1,
|
|
48949
|
+
_v7Recall: 0,
|
|
48950
|
+
_v7FpRate: 0,
|
|
48951
|
+
_v7Precision: 0,
|
|
48952
|
+
_v8Verdict: "OK",
|
|
48953
|
+
_v8Lift: 48.52
|
|
48954
|
+
},
|
|
48955
|
+
"docs/expired-code-example": {
|
|
47485
48956
|
recall: 0,
|
|
47486
48957
|
fpRate: 0,
|
|
47487
48958
|
ratio: 0,
|
|
47488
48959
|
precision: 0,
|
|
47489
|
-
lastCalibratedAt: "2026-
|
|
48960
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
48961
|
+
verdict: "INVERTED",
|
|
48962
|
+
_calibrationNote: "v8.5 calibration (v0.18.9, 2026-07-01): v7+v8 combined corpus (252080 neg + 294178 pos). v8.5 TP=0, FP=3, P=0.0%, FPR=0.00%, lift=0.00. v7 was DORMANT (TP=0, FP=0, lift=1.00). v8 was INVERTED (TP=0, FP=3).",
|
|
48963
|
+
aiSpecific: false,
|
|
48964
|
+
_v7Verdict: "DORMANT",
|
|
48965
|
+
_v7Lift: 1,
|
|
48966
|
+
_v7Recall: 0,
|
|
48967
|
+
_v7FpRate: 0,
|
|
48968
|
+
_v7Precision: 0,
|
|
48969
|
+
_v8Verdict: "INVERTED",
|
|
48970
|
+
_v8Lift: 0,
|
|
48971
|
+
defaultOff: true
|
|
48972
|
+
},
|
|
48973
|
+
"docs/stale-function-reference": {
|
|
48974
|
+
recall: 26e-4,
|
|
48975
|
+
fpRate: 5e-4,
|
|
48976
|
+
ratio: 1638.47,
|
|
48977
|
+
precision: 0.8515,
|
|
48978
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
48979
|
+
verdict: "USEFUL",
|
|
48980
|
+
_calibrationNote: "v8.5 calibration (v0.18.9, 2026-07-01): v7+v8 combined corpus (252080 neg + 294178 pos). v8.5 TP=751, FP=131, P=85.1%, FPR=0.05%, lift=1638.47. v7 was DORMANT (TP=0, FP=0, lift=1.00). v8 was USEFUL (TP=751, FP=131).",
|
|
48981
|
+
aiSpecific: false,
|
|
48982
|
+
_v7Verdict: "DORMANT",
|
|
48983
|
+
_v7Lift: 1,
|
|
48984
|
+
_v7Recall: 0,
|
|
48985
|
+
_v7FpRate: 0,
|
|
48986
|
+
_v7Precision: 0,
|
|
48987
|
+
_v8Verdict: "USEFUL",
|
|
48988
|
+
_v8Lift: 446.32
|
|
48989
|
+
},
|
|
48990
|
+
"docs/stale-package-reference": {
|
|
48991
|
+
recall: 2e-4,
|
|
48992
|
+
fpRate: 4e-4,
|
|
48993
|
+
ratio: 939.43,
|
|
48994
|
+
precision: 0.3429,
|
|
48995
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
48996
|
+
verdict: "OK",
|
|
48997
|
+
_calibrationNote: "v8.5 calibration (v0.18.9, 2026-07-01): v7+v8 combined corpus (252080 neg + 294178 pos). v8.5 TP=48, FP=92, P=34.3%, FPR=0.04%, lift=939.43. v7 was DORMANT (TP=0, FP=0, lift=1.00). v8 was OK (TP=48, FP=92).",
|
|
48998
|
+
aiSpecific: false,
|
|
48999
|
+
_v7Verdict: "DORMANT",
|
|
49000
|
+
_v7Lift: 1,
|
|
49001
|
+
_v7Recall: 0,
|
|
49002
|
+
_v7FpRate: 0,
|
|
49003
|
+
_v7Precision: 0,
|
|
49004
|
+
_v8Verdict: "OK",
|
|
49005
|
+
_v8Lift: 255.9
|
|
49006
|
+
},
|
|
49007
|
+
"dup/identical-block": {
|
|
49008
|
+
recall: 0,
|
|
49009
|
+
fpRate: 0,
|
|
49010
|
+
ratio: 1,
|
|
49011
|
+
precision: 0,
|
|
49012
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
47490
49013
|
verdict: "DORMANT",
|
|
47491
|
-
|
|
47492
|
-
|
|
47493
|
-
|
|
49014
|
+
_calibrationNote: "v0.19: new rule, not yet calibrated. v8.5 calibration does not run dup/* rules. Scheduled for v0.20 calibration on near-dup corpus.",
|
|
49015
|
+
aiSpecific: false,
|
|
49016
|
+
_v7Verdict: "DORMANT",
|
|
49017
|
+
_v7Lift: 1,
|
|
49018
|
+
_v7Recall: 0,
|
|
49019
|
+
_v7FpRate: 0,
|
|
49020
|
+
_v7Precision: 0,
|
|
49021
|
+
_v8Verdict: "DORMANT",
|
|
49022
|
+
_v8Lift: 1,
|
|
49023
|
+
defaultOff: true
|
|
47494
49024
|
},
|
|
47495
|
-
"
|
|
49025
|
+
"go/error-wrap-without-context": {
|
|
47496
49026
|
recall: 0,
|
|
47497
49027
|
fpRate: 0,
|
|
47498
|
-
ratio:
|
|
49028
|
+
ratio: 1,
|
|
47499
49029
|
precision: 0,
|
|
47500
|
-
lastCalibratedAt: "2026-
|
|
49030
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
47501
49031
|
verdict: "DORMANT",
|
|
47502
|
-
|
|
47503
|
-
|
|
47504
|
-
|
|
49032
|
+
_calibrationNote: "v0.19: new rule (fmt.Errorf wrap with generic message \u2014 needs operation context). Not yet calibrated. Scheduled for v9 calibration.",
|
|
49033
|
+
aiSpecific: true,
|
|
49034
|
+
_v7Verdict: "DORMANT",
|
|
49035
|
+
_v7Lift: 1,
|
|
49036
|
+
_v7Recall: 0,
|
|
49037
|
+
_v7FpRate: 0,
|
|
49038
|
+
_v7Precision: 0,
|
|
49039
|
+
_v8Verdict: "DORMANT",
|
|
49040
|
+
_v8Lift: 1,
|
|
49041
|
+
defaultOff: true
|
|
47505
49042
|
},
|
|
47506
|
-
"
|
|
49043
|
+
"go/nil-slice-vs-empty": {
|
|
47507
49044
|
recall: 0,
|
|
47508
49045
|
fpRate: 0,
|
|
47509
|
-
ratio:
|
|
49046
|
+
ratio: 1,
|
|
47510
49047
|
precision: 0,
|
|
47511
|
-
lastCalibratedAt: "2026-
|
|
49048
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
47512
49049
|
verdict: "DORMANT",
|
|
47513
|
-
|
|
47514
|
-
|
|
47515
|
-
|
|
49050
|
+
_calibrationNote: "v0.19: new rule (Variable declared nil slice but assigned empty slice). Not yet calibrated. Scheduled for v9 calibration.",
|
|
49051
|
+
aiSpecific: true,
|
|
49052
|
+
_v7Verdict: "DORMANT",
|
|
49053
|
+
_v7Lift: 1,
|
|
49054
|
+
_v7Recall: 0,
|
|
49055
|
+
_v7FpRate: 0,
|
|
49056
|
+
_v7Precision: 0,
|
|
49057
|
+
_v8Verdict: "DORMANT",
|
|
49058
|
+
_v8Lift: 1,
|
|
49059
|
+
defaultOff: true
|
|
47516
49060
|
},
|
|
47517
|
-
"
|
|
49061
|
+
"go/struct-tag-inconsistency": {
|
|
47518
49062
|
recall: 0,
|
|
47519
49063
|
fpRate: 0,
|
|
47520
|
-
ratio:
|
|
49064
|
+
ratio: 1,
|
|
47521
49065
|
precision: 0,
|
|
47522
|
-
lastCalibratedAt: "2026-
|
|
49066
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
47523
49067
|
verdict: "DORMANT",
|
|
47524
|
-
|
|
47525
|
-
|
|
47526
|
-
|
|
49068
|
+
_calibrationNote: "v0.19: new rule (Struct fields mix json tag styles). Not yet calibrated. Scheduled for v9 calibration.",
|
|
49069
|
+
aiSpecific: true,
|
|
49070
|
+
_v7Verdict: "DORMANT",
|
|
49071
|
+
_v7Lift: 1,
|
|
49072
|
+
_v7Recall: 0,
|
|
49073
|
+
_v7FpRate: 0,
|
|
49074
|
+
_v7Precision: 0,
|
|
49075
|
+
_v8Verdict: "DORMANT",
|
|
49076
|
+
_v8Lift: 1,
|
|
49077
|
+
defaultOff: true
|
|
47527
49078
|
},
|
|
47528
|
-
"
|
|
49079
|
+
"layout/forced-layout": {
|
|
47529
49080
|
recall: 0,
|
|
47530
49081
|
fpRate: 0,
|
|
47531
49082
|
ratio: 0,
|
|
47532
49083
|
precision: 0,
|
|
47533
|
-
lastCalibratedAt: "2026-
|
|
49084
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
47534
49085
|
verdict: "DORMANT",
|
|
47535
|
-
|
|
47536
|
-
|
|
47537
|
-
|
|
49086
|
+
_calibrationNote: "v8.5 calibration (v0.18.9, 2026-07-01): rule did not fire on v8.5 corpus (252080 neg + 294178 pos = 546258 files). Preserved v7 data. v7 verdict=DORMANT, v7 lift=0, v7 recall=0, v7 FPR=0, v7 precision=0.",
|
|
49087
|
+
aiSpecific: true,
|
|
49088
|
+
_v7Verdict: "DORMANT",
|
|
49089
|
+
_v7Lift: 0,
|
|
49090
|
+
_v7Recall: 0,
|
|
49091
|
+
_v7FpRate: 0,
|
|
49092
|
+
_v7Precision: 0,
|
|
49093
|
+
_v8Verdict: "DORMANT",
|
|
49094
|
+
_v8Lift: 1,
|
|
49095
|
+
defaultOff: true
|
|
47538
49096
|
},
|
|
47539
|
-
"
|
|
47540
|
-
recall:
|
|
47541
|
-
fpRate:
|
|
47542
|
-
ratio:
|
|
47543
|
-
precision: 0.
|
|
47544
|
-
lastCalibratedAt: "2026-
|
|
47545
|
-
verdict: "HYGIENE",
|
|
47546
|
-
_calibrationNote: "v7 corpus re-calibration (2026-06-27, min-date=2025-01-01): 184488 neg + 239054 pos. HYGIENE \u2014 TP=2028, FP=521, P=79.6%, FPR=0.28%, lift=3.0. aiSpecific=False.",
|
|
47547
|
-
aiSpecific: false
|
|
47548
|
-
},
|
|
47549
|
-
"product/ux-pattern-fragmentation": {
|
|
47550
|
-
recall: 1e-4,
|
|
47551
|
-
fpRate: 0,
|
|
47552
|
-
ratio: 3.09,
|
|
47553
|
-
precision: 0.8,
|
|
47554
|
-
lastCalibratedAt: "2026-06-27T12:00:00Z",
|
|
49097
|
+
"layout/gap-monopoly": {
|
|
49098
|
+
recall: 3e-4,
|
|
49099
|
+
fpRate: 1e-4,
|
|
49100
|
+
ratio: 8859.33,
|
|
49101
|
+
precision: 0.8083,
|
|
49102
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
47555
49103
|
verdict: "USEFUL",
|
|
47556
|
-
_calibrationNote: "
|
|
47557
|
-
aiSpecific:
|
|
49104
|
+
_calibrationNote: "v8.5 calibration (v0.18.9, 2026-07-01): v7+v8 combined corpus (252080 neg + 294178 pos). v8.5 TP=97, FP=23, P=80.8%, FPR=0.01%, lift=8859.33. v7 was USEFUL (TP=88, FP=23, lift=6322.11). v8 was USEFUL (TP=9, FP=0).",
|
|
49105
|
+
aiSpecific: false,
|
|
49106
|
+
_v7Verdict: "USEFUL",
|
|
49107
|
+
_v7Lift: 6322.11,
|
|
49108
|
+
_v7Recall: 4e-4,
|
|
49109
|
+
_v7FpRate: 1e-4,
|
|
49110
|
+
_v7Precision: 0.7928,
|
|
49111
|
+
_v8Verdict: "USEFUL",
|
|
49112
|
+
_v8Lift: 99999
|
|
47558
49113
|
},
|
|
47559
|
-
"
|
|
47560
|
-
recall:
|
|
47561
|
-
fpRate:
|
|
47562
|
-
ratio:
|
|
47563
|
-
precision: 0.
|
|
47564
|
-
lastCalibratedAt: "2026-
|
|
47565
|
-
verdict: "
|
|
47566
|
-
_calibrationNote: "
|
|
47567
|
-
aiSpecific: true
|
|
49114
|
+
"layout/math-element-uniformity": {
|
|
49115
|
+
recall: 29e-4,
|
|
49116
|
+
fpRate: 1e-3,
|
|
49117
|
+
ratio: 770.74,
|
|
49118
|
+
precision: 0.7705,
|
|
49119
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
49120
|
+
verdict: "USEFUL",
|
|
49121
|
+
_calibrationNote: "v8.5 calibration (v0.18.9, 2026-07-01): v7+v8 combined corpus (252080 neg + 294178 pos). v8.5 TP=846, FP=252, P=77.0%, FPR=0.10%, lift=770.74. v7 was USEFUL (TP=666, FP=225, lift=609.32). v8 was USEFUL (TP=180, FP=27).",
|
|
49122
|
+
aiSpecific: true,
|
|
49123
|
+
_v7Verdict: "USEFUL",
|
|
49124
|
+
_v7Lift: 609.32,
|
|
49125
|
+
_v7Recall: 28e-4,
|
|
49126
|
+
_v7FpRate: 12e-4,
|
|
49127
|
+
_v7Precision: 0.7475,
|
|
49128
|
+
_v8Verdict: "USEFUL",
|
|
49129
|
+
_v8Lift: 2211.5
|
|
47568
49130
|
},
|
|
47569
|
-
"
|
|
47570
|
-
recall:
|
|
47571
|
-
fpRate:
|
|
47572
|
-
ratio:
|
|
47573
|
-
precision: 0.
|
|
47574
|
-
lastCalibratedAt: "2026-
|
|
49131
|
+
"layout/math-grid-uniformity": {
|
|
49132
|
+
recall: 3e-4,
|
|
49133
|
+
fpRate: 1e-4,
|
|
49134
|
+
ratio: 5839.98,
|
|
49135
|
+
precision: 0.7182,
|
|
49136
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
47575
49137
|
verdict: "USEFUL",
|
|
47576
|
-
_calibrationNote: "
|
|
47577
|
-
aiSpecific:
|
|
49138
|
+
_calibrationNote: "v8.5 calibration (v0.18.9, 2026-07-01): v7+v8 combined corpus (252080 neg + 294178 pos). v8.5 TP=79, FP=31, P=71.8%, FPR=0.01%, lift=5839.98. v7 was USEFUL (TP=67, FP=30, lift=4222.91). v8 was USEFUL (TP=12, FP=1).",
|
|
49139
|
+
aiSpecific: true,
|
|
49140
|
+
_v7Verdict: "USEFUL",
|
|
49141
|
+
_v7Lift: 4222.91,
|
|
49142
|
+
_v7Recall: 3e-4,
|
|
49143
|
+
_v7FpRate: 2e-4,
|
|
49144
|
+
_v7Precision: 0.6907,
|
|
49145
|
+
_v8Verdict: "USEFUL",
|
|
49146
|
+
_v8Lift: 63384.92
|
|
47578
49147
|
},
|
|
47579
|
-
"
|
|
47580
|
-
recall:
|
|
47581
|
-
fpRate:
|
|
47582
|
-
ratio:
|
|
47583
|
-
precision: 0.
|
|
47584
|
-
lastCalibratedAt: "2026-
|
|
47585
|
-
verdict: "
|
|
47586
|
-
_calibrationNote: "
|
|
47587
|
-
|
|
47588
|
-
|
|
49148
|
+
"layout/spacing-grid": {
|
|
49149
|
+
recall: 2e-4,
|
|
49150
|
+
fpRate: 2e-4,
|
|
49151
|
+
ratio: 4051.29,
|
|
49152
|
+
precision: 0.6429,
|
|
49153
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
49154
|
+
verdict: "USEFUL",
|
|
49155
|
+
_calibrationNote: "v8.5 calibration (v0.18.9, 2026-07-01): v7+v8 combined corpus (252080 neg + 294178 pos). v8.5 TP=72, FP=40, P=64.3%, FPR=0.02%, lift=4051.29. v7 was USEFUL (TP=39, FP=15, lift=8831.00). v8 was USEFUL (TP=33, FP=25).",
|
|
49156
|
+
aiSpecific: false,
|
|
49157
|
+
_v7Verdict: "USEFUL",
|
|
49158
|
+
_v7Lift: 8831,
|
|
49159
|
+
_v7Recall: 2e-4,
|
|
49160
|
+
_v7FpRate: 1e-4,
|
|
49161
|
+
_v7Precision: 0.7222,
|
|
49162
|
+
_v8Verdict: "USEFUL",
|
|
49163
|
+
_v8Lift: 1562.77
|
|
47589
49164
|
},
|
|
47590
|
-
"
|
|
47591
|
-
recall:
|
|
49165
|
+
"logic/bayesian-conditional": {
|
|
49166
|
+
recall: 0,
|
|
47592
49167
|
fpRate: 0,
|
|
47593
|
-
ratio:
|
|
47594
|
-
precision: 0
|
|
47595
|
-
lastCalibratedAt: "2026-
|
|
49168
|
+
ratio: 0,
|
|
49169
|
+
precision: 0,
|
|
49170
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
49171
|
+
verdict: "DORMANT",
|
|
49172
|
+
_calibrationNote: "v8.5 calibration (v0.18.9, 2026-07-01): rule did not fire on v8.5 corpus (252080 neg + 294178 pos = 546258 files). Preserved v7 data. v7 verdict=DORMANT, v7 lift=0, v7 recall=0, v7 FPR=0, v7 precision=0.",
|
|
49173
|
+
aiSpecific: true,
|
|
49174
|
+
_v7Verdict: "DORMANT",
|
|
49175
|
+
_v7Lift: 0,
|
|
49176
|
+
_v7Recall: 0,
|
|
49177
|
+
_v7FpRate: 0,
|
|
49178
|
+
_v7Precision: 0,
|
|
49179
|
+
_v8Verdict: "DORMANT",
|
|
49180
|
+
_v8Lift: 1,
|
|
49181
|
+
defaultOff: true
|
|
49182
|
+
},
|
|
49183
|
+
"logic/boundary-violation": {
|
|
49184
|
+
recall: 0.0274,
|
|
49185
|
+
fpRate: 0.0137,
|
|
49186
|
+
ratio: 51.32,
|
|
49187
|
+
precision: 0.7006,
|
|
49188
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
47596
49189
|
verdict: "USEFUL",
|
|
47597
|
-
_calibrationNote: "
|
|
47598
|
-
aiSpecific:
|
|
49190
|
+
_calibrationNote: "v8.5 calibration (v0.18.9, 2026-07-01): v7+v8 combined corpus (252080 neg + 294178 pos). v8.5 TP=8051, FP=3441, P=70.1%, FPR=1.37%, lift=51.32. v7 was USEFUL (TP=6282, FP=3235, lift=37.42). v8 was USEFUL (TP=1769, FP=206).",
|
|
49191
|
+
aiSpecific: false,
|
|
49192
|
+
_v7Verdict: "USEFUL",
|
|
49193
|
+
_v7Lift: 37.42,
|
|
49194
|
+
_v7Recall: 0.0265,
|
|
49195
|
+
_v7FpRate: 0.0176,
|
|
49196
|
+
_v7Precision: 0.6601,
|
|
49197
|
+
_v8Verdict: "USEFUL",
|
|
49198
|
+
_v8Lift: 298.57
|
|
47599
49199
|
},
|
|
47600
49200
|
"logic/ghost-defensive": {
|
|
47601
49201
|
recall: 1e-4,
|
|
47602
49202
|
fpRate: 0,
|
|
47603
|
-
ratio:
|
|
47604
|
-
precision: 0.
|
|
47605
|
-
lastCalibratedAt: "2026-
|
|
49203
|
+
ratio: 112035.56,
|
|
49204
|
+
precision: 0.8889,
|
|
49205
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
47606
49206
|
verdict: "USEFUL",
|
|
47607
|
-
_calibrationNote: "
|
|
47608
|
-
aiSpecific: true
|
|
49207
|
+
_calibrationNote: "v8.5 calibration (v0.18.9, 2026-07-01): v7+v8 combined corpus (252080 neg + 294178 pos). v8.5 TP=16, FP=2, P=88.9%, FPR=0.00%, lift=112035.56. v7 was USEFUL (TP=15, FP=2, lift=80917.50). v8 was USEFUL (TP=1, FP=0). v0.19 default-on (explicit defaultOff: false): P 88.9% / 112k lift \u2014 code smell.",
|
|
49208
|
+
aiSpecific: true,
|
|
49209
|
+
_v7Verdict: "USEFUL",
|
|
49210
|
+
_v7Lift: 80917.5,
|
|
49211
|
+
_v7Recall: 1e-4,
|
|
49212
|
+
_v7FpRate: 0,
|
|
49213
|
+
_v7Precision: 0.8824,
|
|
49214
|
+
_v8Verdict: "USEFUL",
|
|
49215
|
+
_v8Lift: 99999,
|
|
49216
|
+
defaultOff: false
|
|
47609
49217
|
},
|
|
47610
|
-
"
|
|
47611
|
-
recall: 0,
|
|
47612
|
-
fpRate: 0,
|
|
47613
|
-
ratio:
|
|
47614
|
-
precision: 0.
|
|
47615
|
-
lastCalibratedAt: "2026-
|
|
47616
|
-
verdict: "
|
|
47617
|
-
_calibrationNote: "
|
|
47618
|
-
aiSpecific: false
|
|
49218
|
+
"logic/heaps-deviation": {
|
|
49219
|
+
recall: 0.0126,
|
|
49220
|
+
fpRate: 0.0178,
|
|
49221
|
+
ratio: 25.54,
|
|
49222
|
+
precision: 0.4536,
|
|
49223
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
49224
|
+
verdict: "OK",
|
|
49225
|
+
_calibrationNote: "v8.5 calibration (v0.18.9, 2026-07-01): v7+v8 combined corpus (252080 neg + 294178 pos). v8.5 TP=3716, FP=4477, P=45.4%, FPR=1.78%, lift=25.54. v7 was USEFUL (TP=2924, FP=2430, lift=41.22). v8 was OK (TP=792, FP=2047).",
|
|
49226
|
+
aiSpecific: false,
|
|
49227
|
+
_v7Verdict: "USEFUL",
|
|
49228
|
+
_v7Lift: 41.22,
|
|
49229
|
+
_v7Recall: 0.0123,
|
|
49230
|
+
_v7FpRate: 0.0132,
|
|
49231
|
+
_v7Precision: 0.5461,
|
|
49232
|
+
_v8Verdict: "OK",
|
|
49233
|
+
_v8Lift: 9.36
|
|
47619
49234
|
},
|
|
47620
|
-
"
|
|
47621
|
-
recall:
|
|
47622
|
-
fpRate:
|
|
47623
|
-
ratio:
|
|
47624
|
-
precision:
|
|
47625
|
-
lastCalibratedAt: "2026-
|
|
49235
|
+
"logic/key-prop-missing": {
|
|
49236
|
+
recall: 16e-4,
|
|
49237
|
+
fpRate: 11e-4,
|
|
49238
|
+
ratio: 574.52,
|
|
49239
|
+
precision: 0.629,
|
|
49240
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
47626
49241
|
verdict: "USEFUL",
|
|
47627
|
-
_calibrationNote: "
|
|
47628
|
-
aiSpecific:
|
|
49242
|
+
_calibrationNote: "v8.5 calibration (v0.18.9, 2026-07-01): v7+v8 combined corpus (252080 neg + 294178 pos). v8.5 TP=468, FP=276, P=62.9%, FPR=0.11%, lift=574.52. v7 was USEFUL (TP=416, FP=250, lift=458.26). v8 was USEFUL (TP=52, FP=26).",
|
|
49243
|
+
aiSpecific: false,
|
|
49244
|
+
_v7Verdict: "USEFUL",
|
|
49245
|
+
_v7Lift: 458.26,
|
|
49246
|
+
_v7Recall: 18e-4,
|
|
49247
|
+
_v7FpRate: 14e-4,
|
|
49248
|
+
_v7Precision: 0.6246,
|
|
49249
|
+
_v8Verdict: "USEFUL",
|
|
49250
|
+
_v8Lift: 1760.69
|
|
47629
49251
|
},
|
|
47630
|
-
"
|
|
47631
|
-
recall:
|
|
47632
|
-
fpRate:
|
|
47633
|
-
ratio:
|
|
47634
|
-
precision: 0.
|
|
47635
|
-
lastCalibratedAt: "2026-
|
|
47636
|
-
verdict: "
|
|
47637
|
-
_calibrationNote: "
|
|
47638
|
-
aiSpecific:
|
|
49252
|
+
"logic/math-any-density": {
|
|
49253
|
+
recall: 17e-4,
|
|
49254
|
+
fpRate: 13e-4,
|
|
49255
|
+
ratio: 464.59,
|
|
49256
|
+
precision: 0.6027,
|
|
49257
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
49258
|
+
verdict: "USEFUL",
|
|
49259
|
+
_calibrationNote: "v8.5 calibration (v0.18.9, 2026-07-01): v7+v8 combined corpus (252080 neg + 294178 pos). v8.5 TP=496, FP=327, P=60.3%, FPR=0.13%, lift=464.59. v7 was USEFUL (TP=376, FP=247, lift=448.16). v8 was USEFUL (TP=120, FP=80).",
|
|
49260
|
+
aiSpecific: true,
|
|
49261
|
+
_v7Verdict: "USEFUL",
|
|
49262
|
+
_v7Lift: 448.16,
|
|
49263
|
+
_v7Recall: 16e-4,
|
|
49264
|
+
_v7FpRate: 13e-4,
|
|
49265
|
+
_v7Precision: 0.6035,
|
|
49266
|
+
_v8Verdict: "USEFUL",
|
|
49267
|
+
_v8Lift: 515
|
|
47639
49268
|
},
|
|
47640
|
-
"
|
|
47641
|
-
recall:
|
|
47642
|
-
fpRate:
|
|
47643
|
-
ratio:
|
|
47644
|
-
precision: 0.
|
|
47645
|
-
lastCalibratedAt: "2026-
|
|
49269
|
+
"logic/math-console-log-storm": {
|
|
49270
|
+
recall: 65e-4,
|
|
49271
|
+
fpRate: 11e-4,
|
|
49272
|
+
ratio: 794.4,
|
|
49273
|
+
precision: 0.8729,
|
|
49274
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
47646
49275
|
verdict: "USEFUL",
|
|
47647
|
-
_calibrationNote: "
|
|
47648
|
-
aiSpecific: true
|
|
49276
|
+
_calibrationNote: "v8.5 calibration (v0.18.9, 2026-07-01): v7+v8 combined corpus (252080 neg + 294178 pos). v8.5 TP=1903, FP=277, P=87.3%, FPR=0.11%, lift=794.40. v7 was USEFUL (TP=1678, FP=193, lift=852.30). v8 was USEFUL (TP=225, FP=84).",
|
|
49277
|
+
aiSpecific: true,
|
|
49278
|
+
_v7Verdict: "USEFUL",
|
|
49279
|
+
_v7Lift: 852.3,
|
|
49280
|
+
_v7Recall: 71e-4,
|
|
49281
|
+
_v7FpRate: 11e-4,
|
|
49282
|
+
_v7Precision: 0.8968,
|
|
49283
|
+
_v8Verdict: "USEFUL",
|
|
49284
|
+
_v8Lift: 595.24
|
|
47649
49285
|
},
|
|
47650
|
-
"
|
|
49286
|
+
"logic/math-gini-class-usage": {
|
|
47651
49287
|
recall: 13e-4,
|
|
47652
|
-
fpRate:
|
|
47653
|
-
ratio:
|
|
47654
|
-
precision: 0.
|
|
47655
|
-
lastCalibratedAt: "2026-
|
|
47656
|
-
verdict: "OK",
|
|
47657
|
-
_calibrationNote: "v7 corpus re-calibration (2026-06-27, min-date=2025-01-01): 184488 neg + 239054 pos. OK \u2014 TP=307, FP=138, P=69.0%, FPR=0.07%, lift=1.7. aiSpecific=True.",
|
|
47658
|
-
aiSpecific: true
|
|
47659
|
-
},
|
|
47660
|
-
"visual/radius-scale-violation": {
|
|
47661
|
-
recall: 4e-4,
|
|
47662
|
-
fpRate: 0,
|
|
47663
|
-
ratio: 24.7,
|
|
47664
|
-
precision: 0.9697,
|
|
47665
|
-
lastCalibratedAt: "2026-06-27T12:00:00Z",
|
|
47666
|
-
verdict: "HYGIENE",
|
|
47667
|
-
_calibrationNote: "v7 corpus re-calibration (2026-06-27, min-date=2025-01-01): 184488 neg + 239054 pos. HYGIENE \u2014 TP=96, FP=3, P=97.0%, FPR=0.00%, lift=24.7. aiSpecific=False.",
|
|
47668
|
-
aiSpecific: false
|
|
47669
|
-
},
|
|
47670
|
-
"test/fake-placeholder": {
|
|
47671
|
-
recall: 53e-4,
|
|
47672
|
-
fpRate: 19e-4,
|
|
47673
|
-
ratio: 2.82,
|
|
47674
|
-
precision: 0.7854,
|
|
47675
|
-
lastCalibratedAt: "2026-06-27T12:00:00Z",
|
|
49288
|
+
fpRate: 2e-4,
|
|
49289
|
+
ratio: 4648.6,
|
|
49290
|
+
precision: 0.8852,
|
|
49291
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
47676
49292
|
verdict: "USEFUL",
|
|
47677
|
-
_calibrationNote: "
|
|
47678
|
-
aiSpecific: true
|
|
47679
|
-
|
|
47680
|
-
|
|
47681
|
-
|
|
47682
|
-
|
|
47683
|
-
|
|
47684
|
-
|
|
47685
|
-
|
|
47686
|
-
verdict: "HYGIENE",
|
|
47687
|
-
_calibrationNote: "v7 corpus re-calibration (2026-06-27, min-date=2025-01-01): 184488 neg + 239054 pos. HYGIENE \u2014 TP=146, FP=125, P=53.9%, FPR=0.07%, lift=0.9. aiSpecific=False.",
|
|
47688
|
-
aiSpecific: false
|
|
47689
|
-
},
|
|
47690
|
-
"perf/cls-image": {
|
|
47691
|
-
recall: 2e-4,
|
|
47692
|
-
fpRate: 3e-4,
|
|
47693
|
-
ratio: 0.8,
|
|
47694
|
-
precision: 0.5104,
|
|
47695
|
-
lastCalibratedAt: "2026-06-27T12:00:00Z",
|
|
47696
|
-
verdict: "HYGIENE",
|
|
47697
|
-
_calibrationNote: "v7 corpus re-calibration (2026-06-27, min-date=2025-01-01): 184488 neg + 239054 pos. HYGIENE \u2014 TP=49, FP=47, P=51.0%, FPR=0.03%, lift=0.8. aiSpecific=False.",
|
|
47698
|
-
aiSpecific: false
|
|
47699
|
-
},
|
|
47700
|
-
"layout/gap-monopoly": {
|
|
47701
|
-
recall: 4e-4,
|
|
47702
|
-
fpRate: 1e-4,
|
|
47703
|
-
ratio: 2.95,
|
|
47704
|
-
precision: 0.7928,
|
|
47705
|
-
lastCalibratedAt: "2026-06-27T12:00:00Z",
|
|
47706
|
-
verdict: "HYGIENE",
|
|
47707
|
-
_calibrationNote: "v7 corpus re-calibration (2026-06-27, min-date=2025-01-01): 184488 neg + 239054 pos. HYGIENE \u2014 TP=88, FP=23, P=79.3%, FPR=0.01%, lift=3.0. aiSpecific=False.",
|
|
47708
|
-
aiSpecific: false
|
|
47709
|
-
},
|
|
47710
|
-
"visual/spacing-scale-violation": {
|
|
47711
|
-
recall: 83e-4,
|
|
47712
|
-
fpRate: 39e-4,
|
|
47713
|
-
ratio: 2.13,
|
|
47714
|
-
precision: 0.7342,
|
|
47715
|
-
lastCalibratedAt: "2026-06-27T12:00:00Z",
|
|
47716
|
-
verdict: "HYGIENE",
|
|
47717
|
-
_calibrationNote: "v7 corpus re-calibration (2026-06-27, min-date=2025-01-01): 184488 neg + 239054 pos. HYGIENE \u2014 TP=1981, FP=717, P=73.4%, FPR=0.39%, lift=2.1. aiSpecific=False.",
|
|
47718
|
-
aiSpecific: false
|
|
47719
|
-
},
|
|
47720
|
-
"visual/inline-style-dominance": {
|
|
47721
|
-
recall: 96e-4,
|
|
47722
|
-
fpRate: 66e-4,
|
|
47723
|
-
ratio: 1.46,
|
|
47724
|
-
precision: 0.6535,
|
|
47725
|
-
lastCalibratedAt: "2026-06-27T12:00:00Z",
|
|
47726
|
-
verdict: "HYGIENE",
|
|
47727
|
-
_calibrationNote: "v7 corpus re-calibration (2026-06-27, min-date=2025-01-01): 184488 neg + 239054 pos. HYGIENE \u2014 TP=2303, FP=1221, P=65.4%, FPR=0.66%, lift=1.5. aiSpecific=False.",
|
|
47728
|
-
aiSpecific: false
|
|
49293
|
+
_calibrationNote: "v8.5 calibration (v0.18.9, 2026-07-01): v7+v8 combined corpus (252080 neg + 294178 pos). v8.5 TP=370, FP=48, P=88.5%, FPR=0.02%, lift=4648.60. v7 was USEFUL (TP=310, FP=47, lift=3388.64). v8 was USEFUL (TP=60, FP=1).",
|
|
49294
|
+
aiSpecific: true,
|
|
49295
|
+
_v7Verdict: "USEFUL",
|
|
49296
|
+
_v7Lift: 3388.64,
|
|
49297
|
+
_v7Recall: 13e-4,
|
|
49298
|
+
_v7FpRate: 3e-4,
|
|
49299
|
+
_v7Precision: 0.8683,
|
|
49300
|
+
_v8Verdict: "USEFUL",
|
|
49301
|
+
_v8Lift: 67541.31
|
|
47729
49302
|
},
|
|
47730
|
-
"
|
|
49303
|
+
"logic/math-variable-name-entropy": {
|
|
47731
49304
|
recall: 2e-4,
|
|
47732
49305
|
fpRate: 1e-4,
|
|
47733
|
-
ratio:
|
|
47734
|
-
precision: 0.
|
|
47735
|
-
lastCalibratedAt: "2026-
|
|
47736
|
-
verdict: "
|
|
47737
|
-
_calibrationNote: "
|
|
47738
|
-
aiSpecific: false
|
|
47739
|
-
|
|
47740
|
-
|
|
47741
|
-
|
|
47742
|
-
|
|
47743
|
-
|
|
47744
|
-
|
|
47745
|
-
|
|
47746
|
-
verdict: "HYGIENE",
|
|
47747
|
-
_calibrationNote: "v7 corpus re-calibration (2026-06-27, min-date=2025-01-01): 184488 neg + 239054 pos. HYGIENE \u2014 TP=2, FP=3, P=40.0%, FPR=0.00%, lift=0.5. aiSpecific=False.",
|
|
47748
|
-
aiSpecific: false
|
|
49306
|
+
ratio: 4548.81,
|
|
49307
|
+
precision: 0.6316,
|
|
49308
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
49309
|
+
verdict: "USEFUL",
|
|
49310
|
+
_calibrationNote: "v8.5 calibration (v0.18.9, 2026-07-01): v7+v8 combined corpus (252080 neg + 294178 pos). v8.5 TP=60, FP=35, P=63.2%, FPR=0.01%, lift=4548.81. v7 was USEFUL (TP=36, FP=26, lift=4096.07). v8 was USEFUL (TP=24, FP=9).",
|
|
49311
|
+
aiSpecific: false,
|
|
49312
|
+
_v7Verdict: "USEFUL",
|
|
49313
|
+
_v7Lift: 4096.07,
|
|
49314
|
+
_v7Recall: 2e-4,
|
|
49315
|
+
_v7FpRate: 1e-4,
|
|
49316
|
+
_v7Precision: 0.5806,
|
|
49317
|
+
_v8Verdict: "USEFUL",
|
|
49318
|
+
_v8Lift: 5548.85
|
|
47749
49319
|
},
|
|
47750
|
-
"
|
|
47751
|
-
recall:
|
|
47752
|
-
fpRate:
|
|
47753
|
-
ratio:
|
|
47754
|
-
precision: 0.
|
|
47755
|
-
lastCalibratedAt: "2026-
|
|
49320
|
+
"logic/optimistic-no-rollback": {
|
|
49321
|
+
recall: 12e-4,
|
|
49322
|
+
fpRate: 2e-4,
|
|
49323
|
+
ratio: 3523.57,
|
|
49324
|
+
precision: 0.8527,
|
|
49325
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
47756
49326
|
verdict: "USEFUL",
|
|
47757
|
-
_calibrationNote: "
|
|
47758
|
-
aiSpecific: true
|
|
49327
|
+
_calibrationNote: "v8.5 calibration (v0.18.9, 2026-07-01): v7+v8 combined corpus (252080 neg + 294178 pos). v8.5 TP=353, FP=61, P=85.3%, FPR=0.02%, lift=3523.57. v7 was USEFUL (TP=281, FP=60, lift=2519.02). v8 was USEFUL (TP=72, FP=1).",
|
|
49328
|
+
aiSpecific: true,
|
|
49329
|
+
_v7Verdict: "USEFUL",
|
|
49330
|
+
_v7Lift: 2519.02,
|
|
49331
|
+
_v7Recall: 12e-4,
|
|
49332
|
+
_v7FpRate: 3e-4,
|
|
49333
|
+
_v7Precision: 0.824,
|
|
49334
|
+
_v8Verdict: "USEFUL",
|
|
49335
|
+
_v8Lift: 67726.36
|
|
47759
49336
|
},
|
|
47760
|
-
"logic/
|
|
49337
|
+
"logic/qwik-hook-leak": {
|
|
47761
49338
|
recall: 0,
|
|
47762
49339
|
fpRate: 0,
|
|
47763
49340
|
ratio: 0,
|
|
47764
49341
|
precision: 0,
|
|
47765
|
-
lastCalibratedAt: "2026-
|
|
49342
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
47766
49343
|
verdict: "DORMANT",
|
|
47767
|
-
|
|
47768
|
-
|
|
47769
|
-
|
|
49344
|
+
_calibrationNote: "v8.5 calibration (v0.18.9, 2026-07-01): rule did not fire on v8.5 corpus (252080 neg + 294178 pos = 546258 files). Preserved v7 data. v7 verdict=DORMANT, v7 lift=0, v7 recall=0, v7 FPR=0, v7 precision=0.",
|
|
49345
|
+
aiSpecific: true,
|
|
49346
|
+
_v7Verdict: "DORMANT",
|
|
49347
|
+
_v7Lift: 0,
|
|
49348
|
+
_v7Recall: 0,
|
|
49349
|
+
_v7FpRate: 0,
|
|
49350
|
+
_v7Precision: 0,
|
|
49351
|
+
_v8Verdict: "DORMANT",
|
|
49352
|
+
_v8Lift: 1,
|
|
49353
|
+
defaultOff: true
|
|
47770
49354
|
},
|
|
47771
|
-
"logic/
|
|
47772
|
-
recall:
|
|
47773
|
-
fpRate:
|
|
47774
|
-
ratio:
|
|
47775
|
-
precision: 0.
|
|
47776
|
-
lastCalibratedAt: "2026-
|
|
47777
|
-
verdict: "
|
|
47778
|
-
_calibrationNote: "
|
|
47779
|
-
aiSpecific:
|
|
47780
|
-
|
|
47781
|
-
|
|
47782
|
-
|
|
47783
|
-
|
|
47784
|
-
|
|
47785
|
-
|
|
47786
|
-
|
|
47787
|
-
verdict: "HYGIENE",
|
|
47788
|
-
_calibrationNote: "v7 corpus re-calibration (2026-06-27, min-date=2025-01-01): 184488 neg + 239054 pos. HYGIENE \u2014 TP=152391, FP=62358, P=71.0%, FPR=33.80%, lift=1.9. aiSpecific=False.",
|
|
47789
|
-
aiSpecific: false
|
|
49355
|
+
"logic/reactive-hook-soup": {
|
|
49356
|
+
recall: 41e-4,
|
|
49357
|
+
fpRate: 6e-4,
|
|
49358
|
+
ratio: 1370.15,
|
|
49359
|
+
precision: 0.8805,
|
|
49360
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
49361
|
+
verdict: "USEFUL",
|
|
49362
|
+
_calibrationNote: "v8.5 calibration (v0.18.9, 2026-07-01): v7+v8 combined corpus (252080 neg + 294178 pos). v8.5 TP=1194, FP=162, P=88.1%, FPR=0.06%, lift=1370.15. v7 was USEFUL (TP=901, FP=162, lift=959.64). v8 was USEFUL (TP=293, FP=0).",
|
|
49363
|
+
aiSpecific: true,
|
|
49364
|
+
_v7Verdict: "USEFUL",
|
|
49365
|
+
_v7Lift: 959.64,
|
|
49366
|
+
_v7Recall: 38e-4,
|
|
49367
|
+
_v7FpRate: 9e-4,
|
|
49368
|
+
_v7Precision: 0.8476,
|
|
49369
|
+
_v8Verdict: "USEFUL",
|
|
49370
|
+
_v8Lift: 99999
|
|
47790
49371
|
},
|
|
47791
49372
|
"logic/zipf-slope-anomaly": {
|
|
47792
|
-
recall: 0.
|
|
47793
|
-
fpRate:
|
|
47794
|
-
ratio:
|
|
47795
|
-
precision: 0.
|
|
47796
|
-
lastCalibratedAt: "2026-
|
|
47797
|
-
verdict: "
|
|
47798
|
-
_calibrationNote: "
|
|
47799
|
-
aiSpecific: false
|
|
49373
|
+
recall: 0.0168,
|
|
49374
|
+
fpRate: 0.0111,
|
|
49375
|
+
ratio: 57.13,
|
|
49376
|
+
precision: 0.6369,
|
|
49377
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
49378
|
+
verdict: "USEFUL",
|
|
49379
|
+
_calibrationNote: "v8.5 calibration (v0.18.9, 2026-07-01): v7+v8 combined corpus (252080 neg + 294178 pos). v8.5 TP=4928, FP=2810, P=63.7%, FPR=1.11%, lift=57.13. v7 was USEFUL (TP=3718, FP=1606, lift=79.75). v8 was USEFUL (TP=1210, FP=1204).",
|
|
49380
|
+
aiSpecific: false,
|
|
49381
|
+
_v7Verdict: "USEFUL",
|
|
49382
|
+
_v7Lift: 79.75,
|
|
49383
|
+
_v7Recall: 0.0157,
|
|
49384
|
+
_v7FpRate: 88e-4,
|
|
49385
|
+
_v7Precision: 0.6983,
|
|
49386
|
+
_v8Verdict: "USEFUL",
|
|
49387
|
+
_v8Lift: 28.59
|
|
47800
49388
|
},
|
|
47801
|
-
"
|
|
47802
|
-
recall:
|
|
49389
|
+
"logic/zombie-state": {
|
|
49390
|
+
recall: 1e-4,
|
|
47803
49391
|
fpRate: 0,
|
|
47804
|
-
ratio:
|
|
47805
|
-
precision: 0.
|
|
47806
|
-
lastCalibratedAt: "2026-
|
|
47807
|
-
verdict: "
|
|
47808
|
-
_calibrationNote: "
|
|
47809
|
-
aiSpecific: true
|
|
49392
|
+
ratio: 119891.71,
|
|
49393
|
+
precision: 0.9512,
|
|
49394
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
49395
|
+
verdict: "USEFUL",
|
|
49396
|
+
_calibrationNote: "v8.5 calibration (v0.18.9, 2026-07-01): v7+v8 combined corpus (252080 neg + 294178 pos). v8.5 TP=39, FP=2, P=95.1%, FPR=0.00%, lift=119891.71. v7 was USEFUL (TP=24, FP=2, lift=84652.15). v8 was USEFUL (TP=15, FP=0).",
|
|
49397
|
+
aiSpecific: true,
|
|
49398
|
+
_v7Verdict: "USEFUL",
|
|
49399
|
+
_v7Lift: 84652.15,
|
|
49400
|
+
_v7Recall: 1e-4,
|
|
49401
|
+
_v7FpRate: 0,
|
|
49402
|
+
_v7Precision: 0.9231,
|
|
49403
|
+
_v8Verdict: "USEFUL",
|
|
49404
|
+
_v8Lift: 99999
|
|
47810
49405
|
},
|
|
47811
|
-
"
|
|
47812
|
-
recall:
|
|
47813
|
-
fpRate:
|
|
47814
|
-
ratio:
|
|
47815
|
-
precision: 0.
|
|
47816
|
-
lastCalibratedAt: "2026-
|
|
47817
|
-
verdict: "
|
|
47818
|
-
_calibrationNote: "
|
|
47819
|
-
aiSpecific:
|
|
49406
|
+
"perf/cls-image": {
|
|
49407
|
+
recall: 2e-4,
|
|
49408
|
+
fpRate: 2e-4,
|
|
49409
|
+
ratio: 2895.78,
|
|
49410
|
+
precision: 0.5514,
|
|
49411
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
49412
|
+
verdict: "USEFUL",
|
|
49413
|
+
_calibrationNote: "v8.5 calibration (v0.18.9, 2026-07-01): v7+v8 combined corpus (252080 neg + 294178 pos). v8.5 TP=59, FP=48, P=55.1%, FPR=0.02%, lift=2895.78. v7 was USEFUL (TP=49, FP=47, lift=1991.85). v8 was USEFUL (TP=10, FP=1).",
|
|
49414
|
+
aiSpecific: false,
|
|
49415
|
+
_v7Verdict: "USEFUL",
|
|
49416
|
+
_v7Lift: 1991.85,
|
|
49417
|
+
_v7Recall: 2e-4,
|
|
49418
|
+
_v7FpRate: 3e-4,
|
|
49419
|
+
_v7Precision: 0.5104,
|
|
49420
|
+
_v8Verdict: "USEFUL",
|
|
49421
|
+
_v8Lift: 62424.55
|
|
47820
49422
|
},
|
|
47821
|
-
"
|
|
47822
|
-
recall: 0.
|
|
47823
|
-
fpRate:
|
|
47824
|
-
ratio:
|
|
47825
|
-
precision: 0.
|
|
47826
|
-
lastCalibratedAt: "2026-
|
|
47827
|
-
verdict: "
|
|
47828
|
-
_calibrationNote: "
|
|
47829
|
-
|
|
47830
|
-
|
|
49423
|
+
"perf/css-bloat": {
|
|
49424
|
+
recall: 0.0126,
|
|
49425
|
+
fpRate: 24e-4,
|
|
49426
|
+
ratio: 365.63,
|
|
49427
|
+
precision: 0.8616,
|
|
49428
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
49429
|
+
verdict: "USEFUL",
|
|
49430
|
+
_calibrationNote: "v8.5 calibration (v0.18.9, 2026-07-01): v7+v8 combined corpus (252080 neg + 294178 pos). v8.5 TP=3697, FP=594, P=86.2%, FPR=0.24%, lift=365.63. v7 was USEFUL (TP=2790, FP=591, lift=256.10). v8 was USEFUL (TP=907, FP=3).",
|
|
49431
|
+
aiSpecific: false,
|
|
49432
|
+
_v7Verdict: "USEFUL",
|
|
49433
|
+
_v7Lift: 256.1,
|
|
49434
|
+
_v7Recall: 0.0118,
|
|
49435
|
+
_v7FpRate: 32e-4,
|
|
49436
|
+
_v7Precision: 0.8252,
|
|
49437
|
+
_v8Verdict: "USEFUL",
|
|
49438
|
+
_v8Lift: 22813.54
|
|
47831
49439
|
},
|
|
47832
|
-
"
|
|
49440
|
+
"perf/halstead-anomaly": {
|
|
47833
49441
|
recall: 0,
|
|
47834
49442
|
fpRate: 0,
|
|
47835
|
-
ratio:
|
|
47836
|
-
precision: 0.
|
|
47837
|
-
lastCalibratedAt: "2026-
|
|
49443
|
+
ratio: 75624,
|
|
49444
|
+
precision: 0.6,
|
|
49445
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
47838
49446
|
verdict: "USEFUL",
|
|
47839
|
-
_calibrationNote: "
|
|
47840
|
-
aiSpecific: true
|
|
49447
|
+
_calibrationNote: "v8.5 calibration (v0.18.9, 2026-07-01): v7+v8 combined corpus (252080 neg + 294178 pos). v8.5 TP=3, FP=2, P=60.0%, FPR=0.00%, lift=75624.00. v7 was USEFUL (TP=3, FP=1, lift=137559.75). v8 was INVERTED (TP=0, FP=1).",
|
|
49448
|
+
aiSpecific: true,
|
|
49449
|
+
_v7Verdict: "USEFUL",
|
|
49450
|
+
_v7Lift: 137559.75,
|
|
49451
|
+
_v7Recall: 0,
|
|
49452
|
+
_v7FpRate: 0,
|
|
49453
|
+
_v7Precision: 0.75,
|
|
49454
|
+
_v8Verdict: "INVERTED",
|
|
49455
|
+
_v8Lift: 0
|
|
47841
49456
|
},
|
|
47842
|
-
"
|
|
47843
|
-
recall:
|
|
47844
|
-
fpRate:
|
|
47845
|
-
ratio:
|
|
47846
|
-
precision: 0.
|
|
47847
|
-
lastCalibratedAt: "2026-
|
|
47848
|
-
verdict: "
|
|
47849
|
-
_calibrationNote: "
|
|
47850
|
-
|
|
47851
|
-
|
|
49457
|
+
"product/terminology-drift": {
|
|
49458
|
+
recall: 91e-4,
|
|
49459
|
+
fpRate: 21e-4,
|
|
49460
|
+
ratio: 397.75,
|
|
49461
|
+
precision: 0.8347,
|
|
49462
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
49463
|
+
verdict: "USEFUL",
|
|
49464
|
+
_calibrationNote: "v8.5 calibration (v0.18.9, 2026-07-01): v7+v8 combined corpus (252080 neg + 294178 pos). v8.5 TP=2671, FP=529, P=83.5%, FPR=0.21%, lift=397.75. v7 was USEFUL (TP=2028, FP=521, lift=280.09). v8 was USEFUL (TP=643, FP=8).",
|
|
49465
|
+
aiSpecific: false,
|
|
49466
|
+
_v7Verdict: "USEFUL",
|
|
49467
|
+
_v7Lift: 280.09,
|
|
49468
|
+
_v7Recall: 86e-4,
|
|
49469
|
+
_v7FpRate: 28e-4,
|
|
49470
|
+
_v7Precision: 0.7956,
|
|
49471
|
+
_v8Verdict: "USEFUL",
|
|
49472
|
+
_v8Lift: 8477.9
|
|
47852
49473
|
},
|
|
47853
|
-
"
|
|
47854
|
-
recall:
|
|
47855
|
-
fpRate:
|
|
47856
|
-
ratio:
|
|
47857
|
-
precision: 0.
|
|
47858
|
-
lastCalibratedAt: "2026-
|
|
47859
|
-
verdict: "
|
|
47860
|
-
_calibrationNote: "
|
|
47861
|
-
|
|
47862
|
-
|
|
49474
|
+
"product/ux-pattern-fragmentation": {
|
|
49475
|
+
recall: 1e-4,
|
|
49476
|
+
fpRate: 0,
|
|
49477
|
+
ratio: 22864.4,
|
|
49478
|
+
precision: 0.8163,
|
|
49479
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
49480
|
+
verdict: "USEFUL",
|
|
49481
|
+
_calibrationNote: "v8.5 calibration (v0.18.9, 2026-07-01): v7+v8 combined corpus (252080 neg + 294178 pos). v8.5 TP=40, FP=9, P=81.6%, FPR=0.00%, lift=22864.40. v7 was USEFUL (TP=32, FP=8, lift=18341.30). v8 was USEFUL (TP=8, FP=1).",
|
|
49482
|
+
aiSpecific: true,
|
|
49483
|
+
_v7Verdict: "USEFUL",
|
|
49484
|
+
_v7Lift: 18341.3,
|
|
49485
|
+
_v7Recall: 1e-4,
|
|
49486
|
+
_v7FpRate: 0,
|
|
49487
|
+
_v7Precision: 0.8,
|
|
49488
|
+
_v8Verdict: "USEFUL",
|
|
49489
|
+
_v8Lift: 61037.33
|
|
47863
49490
|
},
|
|
47864
|
-
"
|
|
47865
|
-
recall:
|
|
49491
|
+
"rust/stringly-typed": {
|
|
49492
|
+
recall: 2e-4,
|
|
47866
49493
|
fpRate: 0,
|
|
47867
|
-
ratio:
|
|
47868
|
-
precision: 0.
|
|
47869
|
-
lastCalibratedAt: "2026-
|
|
47870
|
-
verdict: "
|
|
47871
|
-
_calibrationNote: "
|
|
47872
|
-
|
|
47873
|
-
|
|
49494
|
+
ratio: 24735.12,
|
|
49495
|
+
precision: 0.8831,
|
|
49496
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
49497
|
+
verdict: "USEFUL",
|
|
49498
|
+
_calibrationNote: "v8.5 calibration (v0.18.9, 2026-07-01): v7+v8 combined corpus (252080 neg + 294178 pos). v8.5 TP=68, FP=9, P=88.3%, FPR=0.00%, lift=24735.12. v7 was DORMANT (TP=0, FP=0, lift=1.00). v8 was USEFUL (TP=68, FP=9).",
|
|
49499
|
+
aiSpecific: true,
|
|
49500
|
+
_v7Verdict: "DORMANT",
|
|
49501
|
+
_v7Lift: 1,
|
|
49502
|
+
_v7Recall: 0,
|
|
49503
|
+
_v7FpRate: 0,
|
|
49504
|
+
_v7Precision: 0,
|
|
49505
|
+
_v8Verdict: "USEFUL",
|
|
49506
|
+
_v8Lift: 6737.89
|
|
47874
49507
|
},
|
|
47875
|
-
"
|
|
49508
|
+
"rust/todo-macro": {
|
|
49509
|
+
recall: 1e-4,
|
|
49510
|
+
fpRate: 7e-4,
|
|
49511
|
+
ratio: 210.08,
|
|
49512
|
+
precision: 0.1392,
|
|
49513
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
49514
|
+
verdict: "OK",
|
|
49515
|
+
_calibrationNote: "v8.5 calibration (v0.18.9, 2026-07-01): v7+v8 combined corpus (252080 neg + 294178 pos). v8.5 TP=27, FP=167, P=13.9%, FPR=0.07%, lift=210.08. v7 was DORMANT (TP=0, FP=0, lift=1.00). v8 was OK (TP=27, FP=167).",
|
|
49516
|
+
aiSpecific: true,
|
|
49517
|
+
_v7Verdict: "DORMANT",
|
|
49518
|
+
_v7Lift: 1,
|
|
49519
|
+
_v7Recall: 0,
|
|
49520
|
+
_v7FpRate: 0,
|
|
49521
|
+
_v7Precision: 0,
|
|
49522
|
+
_v8Verdict: "OK",
|
|
49523
|
+
_v8Lift: 57.23
|
|
49524
|
+
},
|
|
49525
|
+
"rust/unused-pub-fn": {
|
|
47876
49526
|
recall: 0,
|
|
47877
49527
|
fpRate: 0,
|
|
47878
|
-
ratio:
|
|
47879
|
-
precision: 0,
|
|
47880
|
-
lastCalibratedAt: "2026-
|
|
49528
|
+
ratio: 10803.43,
|
|
49529
|
+
precision: 0.3,
|
|
49530
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
47881
49531
|
verdict: "OK",
|
|
47882
|
-
_calibrationNote: "v0.
|
|
47883
|
-
aiSpecific: true
|
|
49532
|
+
_calibrationNote: "v8.5 calibration (v0.18.9, 2026-07-01): v7+v8 combined corpus (252080 neg + 294178 pos). v8.5 TP=3, FP=7, P=30.0%, FPR=0.00%, lift=10803.43. v7 was DORMANT (TP=0, FP=0, lift=1.00). v8 was OK (TP=3, FP=7).",
|
|
49533
|
+
aiSpecific: true,
|
|
49534
|
+
_v7Verdict: "DORMANT",
|
|
49535
|
+
_v7Lift: 1,
|
|
49536
|
+
_v7Recall: 0,
|
|
49537
|
+
_v7FpRate: 0,
|
|
49538
|
+
_v7Precision: 0,
|
|
49539
|
+
_v8Verdict: "OK",
|
|
49540
|
+
_v8Lift: 2942.87
|
|
47884
49541
|
},
|
|
47885
|
-
"
|
|
47886
|
-
recall:
|
|
47887
|
-
fpRate:
|
|
47888
|
-
ratio:
|
|
47889
|
-
precision: 0.
|
|
47890
|
-
lastCalibratedAt: "2026-
|
|
49542
|
+
"rust/unwrap-in-production": {
|
|
49543
|
+
recall: 8e-3,
|
|
49544
|
+
fpRate: 77e-4,
|
|
49545
|
+
ratio: 70.81,
|
|
49546
|
+
precision: 0.5475,
|
|
49547
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
47891
49548
|
verdict: "USEFUL",
|
|
47892
|
-
_calibrationNote: "
|
|
47893
|
-
aiSpecific: true
|
|
49549
|
+
_calibrationNote: "v8.5 calibration (v0.18.9, 2026-07-01): v7+v8 combined corpus (252080 neg + 294178 pos). v8.5 TP=2358, FP=1949, P=54.7%, FPR=0.77%, lift=70.81. v7 was DORMANT (TP=0, FP=0, lift=1.00). v8 was USEFUL (TP=2358, FP=1949).",
|
|
49550
|
+
aiSpecific: true,
|
|
49551
|
+
_v7Verdict: "DORMANT",
|
|
49552
|
+
_v7Lift: 1,
|
|
49553
|
+
_v7Recall: 0,
|
|
49554
|
+
_v7FpRate: 0,
|
|
49555
|
+
_v7Precision: 0,
|
|
49556
|
+
_v8Verdict: "USEFUL",
|
|
49557
|
+
_v8Lift: 19.29
|
|
47894
49558
|
},
|
|
47895
|
-
"
|
|
47896
|
-
recall:
|
|
47897
|
-
fpRate:
|
|
47898
|
-
ratio:
|
|
47899
|
-
precision: 0.
|
|
47900
|
-
lastCalibratedAt: "2026-
|
|
49559
|
+
"security/dangerous-cors": {
|
|
49560
|
+
recall: 5e-4,
|
|
49561
|
+
fpRate: 4e-4,
|
|
49562
|
+
ratio: 1721.87,
|
|
49563
|
+
precision: 0.6079,
|
|
49564
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
47901
49565
|
verdict: "USEFUL",
|
|
47902
|
-
_calibrationNote: "
|
|
47903
|
-
aiSpecific: true
|
|
49566
|
+
_calibrationNote: "v8.5 calibration (v0.18.9, 2026-07-01): v7+v8 combined corpus (252080 neg + 294178 pos). v8.5 TP=138, FP=89, P=60.8%, FPR=0.04%, lift=1721.87. v7 was USEFUL (TP=114, FP=84, lift=1257.16). v8 was USEFUL (TP=24, FP=5).",
|
|
49567
|
+
aiSpecific: true,
|
|
49568
|
+
_v7Verdict: "USEFUL",
|
|
49569
|
+
_v7Lift: 1257.16,
|
|
49570
|
+
_v7Recall: 5e-4,
|
|
49571
|
+
_v7FpRate: 5e-4,
|
|
49572
|
+
_v7Precision: 0.5758,
|
|
49573
|
+
_v8Verdict: "USEFUL",
|
|
49574
|
+
_v8Lift: 11365.57
|
|
47904
49575
|
},
|
|
47905
|
-
"
|
|
47906
|
-
recall:
|
|
47907
|
-
fpRate:
|
|
47908
|
-
ratio:
|
|
47909
|
-
precision: 0.
|
|
47910
|
-
lastCalibratedAt: "2026-
|
|
49576
|
+
"security/eval": {
|
|
49577
|
+
recall: 1e-4,
|
|
49578
|
+
fpRate: 2e-4,
|
|
49579
|
+
ratio: 1929.18,
|
|
49580
|
+
precision: 0.4286,
|
|
49581
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
49582
|
+
verdict: "OK",
|
|
49583
|
+
_calibrationNote: "v8.5 calibration (v0.18.9, 2026-07-01): v7+v8 combined corpus (252080 neg + 294178 pos). v8.5 TP=42, FP=56, P=42.9%, FPR=0.02%, lift=1929.18. v7 was DORMANT (TP=0, FP=0, lift=1.00). v8 was OK (TP=42, FP=56).",
|
|
49584
|
+
aiSpecific: false,
|
|
49585
|
+
_v7Verdict: "DORMANT",
|
|
49586
|
+
_v7Lift: 1,
|
|
49587
|
+
_v7Recall: 0,
|
|
49588
|
+
_v7FpRate: 0,
|
|
49589
|
+
_v7Precision: 0,
|
|
49590
|
+
_v8Verdict: "OK",
|
|
49591
|
+
_v8Lift: 525.51
|
|
49592
|
+
},
|
|
49593
|
+
"security/exposed-env-var": {
|
|
49594
|
+
recall: 6e-4,
|
|
49595
|
+
fpRate: 5e-4,
|
|
49596
|
+
ratio: 1055.81,
|
|
49597
|
+
precision: 0.5696,
|
|
49598
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
47911
49599
|
verdict: "USEFUL",
|
|
47912
|
-
_calibrationNote: "
|
|
47913
|
-
aiSpecific:
|
|
49600
|
+
_calibrationNote: "v8.5 calibration (v0.18.9, 2026-07-01): v7+v8 combined corpus (252080 neg + 294178 pos). v8.5 TP=180, FP=136, P=57.0%, FPR=0.05%, lift=1055.81. v7 was USEFUL (TP=146, FP=125, lift=790.50). v8 was USEFUL (TP=34, FP=11).",
|
|
49601
|
+
aiSpecific: false,
|
|
49602
|
+
_v7Verdict: "USEFUL",
|
|
49603
|
+
_v7Lift: 790.5,
|
|
49604
|
+
_v7Recall: 6e-4,
|
|
49605
|
+
_v7FpRate: 7e-4,
|
|
49606
|
+
_v7Precision: 0.5387,
|
|
49607
|
+
_v8Verdict: "USEFUL",
|
|
49608
|
+
_v8Lift: 4716.52
|
|
47914
49609
|
},
|
|
47915
|
-
"
|
|
47916
|
-
recall:
|
|
49610
|
+
"security/fail-open-auth": {
|
|
49611
|
+
recall: 0,
|
|
47917
49612
|
fpRate: 0,
|
|
47918
|
-
ratio:
|
|
47919
|
-
precision:
|
|
47920
|
-
lastCalibratedAt: "2026-
|
|
49613
|
+
ratio: 99999,
|
|
49614
|
+
precision: 1,
|
|
49615
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
47921
49616
|
verdict: "USEFUL",
|
|
47922
|
-
_calibrationNote: "
|
|
47923
|
-
aiSpecific: true
|
|
49617
|
+
_calibrationNote: "v8.5 calibration (v0.18.9, 2026-07-01): v7+v8 combined corpus (252080 neg + 294178 pos). v8.5 TP=1, FP=0, P=100.0%, FPR=0.00%, lift=inf. v7 was USEFUL (TP=1, FP=0, lift=inf). v8 was DORMANT (TP=0, FP=0). v0.19 default-on (explicit defaultOff: false): P 100% / inf lift \u2014 security must always be on.",
|
|
49618
|
+
aiSpecific: true,
|
|
49619
|
+
_v7Verdict: "USEFUL",
|
|
49620
|
+
_v7Lift: 99999,
|
|
49621
|
+
_v7Recall: 0,
|
|
49622
|
+
_v7FpRate: 0,
|
|
49623
|
+
_v7Precision: 1,
|
|
49624
|
+
_v8Verdict: "DORMANT",
|
|
49625
|
+
_v8Lift: 1,
|
|
49626
|
+
defaultOff: false
|
|
47924
49627
|
},
|
|
47925
|
-
"
|
|
47926
|
-
recall:
|
|
49628
|
+
"security/hardcoded-secret": {
|
|
49629
|
+
recall: 14e-4,
|
|
49630
|
+
fpRate: 6e-4,
|
|
49631
|
+
ratio: 1269.08,
|
|
49632
|
+
precision: 0.735,
|
|
49633
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
49634
|
+
verdict: "USEFUL",
|
|
49635
|
+
_calibrationNote: "v8.5 calibration (v0.18.9, 2026-07-01): v7+v8 combined corpus (252080 neg + 294178 pos). v8.5 TP=405, FP=146, P=73.5%, FPR=0.06%, lift=1269.08. v7 was USEFUL (TP=307, FP=138, lift=916.92). v8 was USEFUL (TP=98, FP=8).",
|
|
49636
|
+
aiSpecific: true,
|
|
49637
|
+
_v7Verdict: "USEFUL",
|
|
49638
|
+
_v7Lift: 916.92,
|
|
49639
|
+
_v7Recall: 13e-4,
|
|
49640
|
+
_v7FpRate: 8e-4,
|
|
49641
|
+
_v7Precision: 0.6899,
|
|
49642
|
+
_v8Verdict: "USEFUL",
|
|
49643
|
+
_v8Lift: 7935.57
|
|
49644
|
+
},
|
|
49645
|
+
"security/localstorage-token": {
|
|
49646
|
+
recall: 1e-4,
|
|
47927
49647
|
fpRate: 0,
|
|
47928
|
-
ratio:
|
|
47929
|
-
precision:
|
|
47930
|
-
lastCalibratedAt: "2026-
|
|
49648
|
+
ratio: 99999,
|
|
49649
|
+
precision: 1,
|
|
49650
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
47931
49651
|
verdict: "USEFUL",
|
|
47932
|
-
_calibrationNote: "
|
|
47933
|
-
aiSpecific:
|
|
49652
|
+
_calibrationNote: "v8.5 calibration (v0.18.9, 2026-07-01): v7+v8 combined corpus (252080 neg + 294178 pos). v8.5 TP=17, FP=0, P=100.0%, FPR=0.00%, lift=inf. v7 was DORMANT (TP=0, FP=0, lift=1.00). v8 was USEFUL (TP=17, FP=0).",
|
|
49653
|
+
aiSpecific: false,
|
|
49654
|
+
_v7Verdict: "DORMANT",
|
|
49655
|
+
_v7Lift: 1,
|
|
49656
|
+
_v7Recall: 0,
|
|
49657
|
+
_v7FpRate: 0,
|
|
49658
|
+
_v7Precision: 0,
|
|
49659
|
+
_v8Verdict: "USEFUL",
|
|
49660
|
+
_v8Lift: 99999
|
|
47934
49661
|
},
|
|
47935
|
-
"
|
|
47936
|
-
recall:
|
|
47937
|
-
fpRate:
|
|
47938
|
-
ratio:
|
|
47939
|
-
precision:
|
|
47940
|
-
lastCalibratedAt: "2026-
|
|
49662
|
+
"security/missing-auth-check": {
|
|
49663
|
+
recall: 5e-4,
|
|
49664
|
+
fpRate: 0,
|
|
49665
|
+
ratio: 99999,
|
|
49666
|
+
precision: 1,
|
|
49667
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
47941
49668
|
verdict: "USEFUL",
|
|
47942
|
-
_calibrationNote: "
|
|
47943
|
-
aiSpecific:
|
|
49669
|
+
_calibrationNote: "v8.5 calibration (v0.18.9, 2026-07-01): v7+v8 combined corpus (252080 neg + 294178 pos). v8.5 TP=157, FP=0, P=100.0%, FPR=0.00%, lift=inf. v7 was DORMANT (TP=0, FP=0, lift=1.00). v8 was USEFUL (TP=157, FP=0).",
|
|
49670
|
+
aiSpecific: false,
|
|
49671
|
+
_v7Verdict: "DORMANT",
|
|
49672
|
+
_v7Lift: 1,
|
|
49673
|
+
_v7Recall: 0,
|
|
49674
|
+
_v7FpRate: 0,
|
|
49675
|
+
_v7Precision: 0,
|
|
49676
|
+
_v8Verdict: "USEFUL",
|
|
49677
|
+
_v8Lift: 99999
|
|
47944
49678
|
},
|
|
47945
|
-
"
|
|
47946
|
-
recall:
|
|
47947
|
-
fpRate:
|
|
47948
|
-
ratio:
|
|
47949
|
-
precision: 0.
|
|
47950
|
-
lastCalibratedAt: "2026-
|
|
49679
|
+
"security/public-admin-route": {
|
|
49680
|
+
recall: 38e-4,
|
|
49681
|
+
fpRate: 38e-4,
|
|
49682
|
+
ratio: 142.2,
|
|
49683
|
+
precision: 0.5376,
|
|
49684
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
47951
49685
|
verdict: "USEFUL",
|
|
47952
|
-
_calibrationNote: "
|
|
47953
|
-
aiSpecific:
|
|
49686
|
+
_calibrationNote: "v8.5 calibration (v0.18.9, 2026-07-01): v7+v8 combined corpus (252080 neg + 294178 pos). v8.5 TP=1108, FP=953, P=53.8%, FPR=0.38%, lift=142.20. v7 was DORMANT (TP=0, FP=0, lift=1.00). v8 was USEFUL (TP=1108, FP=953).",
|
|
49687
|
+
aiSpecific: false,
|
|
49688
|
+
_v7Verdict: "DORMANT",
|
|
49689
|
+
_v7Lift: 1,
|
|
49690
|
+
_v7Recall: 0,
|
|
49691
|
+
_v7FpRate: 0,
|
|
49692
|
+
_v7Precision: 0,
|
|
49693
|
+
_v8Verdict: "USEFUL",
|
|
49694
|
+
_v8Lift: 38.74
|
|
47954
49695
|
},
|
|
47955
|
-
"
|
|
47956
|
-
recall:
|
|
47957
|
-
fpRate:
|
|
47958
|
-
ratio:
|
|
47959
|
-
precision: 0.
|
|
47960
|
-
lastCalibratedAt: "2026-
|
|
49696
|
+
"security/sql-construction": {
|
|
49697
|
+
recall: 32e-4,
|
|
49698
|
+
fpRate: 15e-4,
|
|
49699
|
+
ratio: 485.42,
|
|
49700
|
+
precision: 0.7183,
|
|
49701
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
47961
49702
|
verdict: "USEFUL",
|
|
47962
|
-
_calibrationNote: "
|
|
47963
|
-
aiSpecific: true
|
|
49703
|
+
_calibrationNote: "v8.5 calibration (v0.18.9, 2026-07-01): v7+v8 combined corpus (252080 neg + 294178 pos). v8.5 TP=951, FP=373, P=71.8%, FPR=0.15%, lift=485.42. v7 was USEFUL (TP=710, FP=336, lift=370.52). v8 was USEFUL (TP=241, FP=37).",
|
|
49704
|
+
aiSpecific: true,
|
|
49705
|
+
_v7Verdict: "USEFUL",
|
|
49706
|
+
_v7Lift: 370.52,
|
|
49707
|
+
_v7Recall: 3e-3,
|
|
49708
|
+
_v7FpRate: 18e-4,
|
|
49709
|
+
_v7Precision: 0.6788,
|
|
49710
|
+
_v8Verdict: "USEFUL",
|
|
49711
|
+
_v8Lift: 1608.86
|
|
47964
49712
|
},
|
|
47965
|
-
"
|
|
47966
|
-
recall:
|
|
49713
|
+
"security/target-blank-no-noopener": {
|
|
49714
|
+
recall: 4e-4,
|
|
47967
49715
|
fpRate: 0,
|
|
47968
|
-
ratio:
|
|
47969
|
-
precision: 0,
|
|
47970
|
-
lastCalibratedAt: "2026-
|
|
47971
|
-
verdict: "
|
|
47972
|
-
|
|
47973
|
-
|
|
47974
|
-
|
|
49716
|
+
ratio: 26141.63,
|
|
49717
|
+
precision: 0.9333,
|
|
49718
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
49719
|
+
verdict: "USEFUL",
|
|
49720
|
+
_calibrationNote: "v8.5 calibration (v0.18.9, 2026-07-01): v7+v8 combined corpus (252080 neg + 294178 pos). v8.5 TP=126, FP=9, P=93.3%, FPR=0.00%, lift=26141.63. v7 was DORMANT (TP=0, FP=0, lift=1.00). v8 was USEFUL (TP=126, FP=9).",
|
|
49721
|
+
aiSpecific: false,
|
|
49722
|
+
_v7Verdict: "DORMANT",
|
|
49723
|
+
_v7Lift: 1,
|
|
49724
|
+
_v7Recall: 0,
|
|
49725
|
+
_v7FpRate: 0,
|
|
49726
|
+
_v7Precision: 0,
|
|
49727
|
+
_v8Verdict: "USEFUL",
|
|
49728
|
+
_v8Lift: 7121.02
|
|
47975
49729
|
},
|
|
47976
|
-
"
|
|
47977
|
-
recall:
|
|
49730
|
+
"security/unsafe-html-render": {
|
|
49731
|
+
recall: 13e-4,
|
|
49732
|
+
fpRate: 11e-4,
|
|
49733
|
+
ratio: 513.12,
|
|
49734
|
+
precision: 0.574,
|
|
49735
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
49736
|
+
verdict: "USEFUL",
|
|
49737
|
+
_calibrationNote: "v8.5 calibration (v0.18.9, 2026-07-01): v7+v8 combined corpus (252080 neg + 294178 pos). v8.5 TP=380, FP=282, P=57.4%, FPR=0.11%, lift=513.12. v7 was USEFUL (TP=312, FP=160, lift=757.74). v8 was OK (TP=68, FP=122).",
|
|
49738
|
+
aiSpecific: false,
|
|
49739
|
+
_v7Verdict: "USEFUL",
|
|
49740
|
+
_v7Lift: 757.74,
|
|
49741
|
+
_v7Recall: 13e-4,
|
|
49742
|
+
_v7FpRate: 9e-4,
|
|
49743
|
+
_v7Precision: 0.661,
|
|
49744
|
+
_v8Verdict: "OK",
|
|
49745
|
+
_v8Lift: 201.44
|
|
49746
|
+
},
|
|
49747
|
+
"test/duplicate-setup": {
|
|
49748
|
+
recall: 1e-4,
|
|
47978
49749
|
fpRate: 0,
|
|
47979
|
-
ratio:
|
|
47980
|
-
precision: 0,
|
|
47981
|
-
lastCalibratedAt: "2026-
|
|
47982
|
-
verdict: "
|
|
47983
|
-
|
|
47984
|
-
|
|
47985
|
-
|
|
49750
|
+
ratio: 51016.19,
|
|
49751
|
+
precision: 0.8095,
|
|
49752
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
49753
|
+
verdict: "USEFUL",
|
|
49754
|
+
_calibrationNote: "v8.5 calibration (v0.18.9, 2026-07-01): v7+v8 combined corpus (252080 neg + 294178 pos). v8.5 TP=17, FP=4, P=81.0%, FPR=0.00%, lift=51016.19. v7 was USEFUL (TP=14, FP=3, lift=50348.67). v8 was USEFUL (TP=3, FP=1).",
|
|
49755
|
+
aiSpecific: true,
|
|
49756
|
+
_v7Verdict: "USEFUL",
|
|
49757
|
+
_v7Lift: 50348.67,
|
|
49758
|
+
_v7Recall: 1e-4,
|
|
49759
|
+
_v7FpRate: 0,
|
|
49760
|
+
_v7Precision: 0.8235,
|
|
49761
|
+
_v8Verdict: "USEFUL",
|
|
49762
|
+
_v8Lift: 51500.25
|
|
47986
49763
|
},
|
|
47987
|
-
"
|
|
49764
|
+
"test/fake-placeholder": {
|
|
49765
|
+
recall: 51e-4,
|
|
49766
|
+
fpRate: 15e-4,
|
|
49767
|
+
ratio: 547.47,
|
|
49768
|
+
precision: 0.8014,
|
|
49769
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
49770
|
+
verdict: "USEFUL",
|
|
49771
|
+
_calibrationNote: "v8.5 calibration (v0.18.9, 2026-07-01): v7+v8 combined corpus (252080 neg + 294178 pos). v8.5 TP=1489, FP=369, P=80.1%, FPR=0.15%, lift=547.47. v7 was USEFUL (TP=1259, FP=344, lift=418.76). v8 was USEFUL (TP=230, FP=25).",
|
|
49772
|
+
aiSpecific: true,
|
|
49773
|
+
_v7Verdict: "USEFUL",
|
|
49774
|
+
_v7Lift: 418.76,
|
|
49775
|
+
_v7Recall: 53e-4,
|
|
49776
|
+
_v7FpRate: 19e-4,
|
|
49777
|
+
_v7Precision: 0.7854,
|
|
49778
|
+
_v8Verdict: "USEFUL",
|
|
49779
|
+
_v8Lift: 2477.4
|
|
49780
|
+
},
|
|
49781
|
+
"test/missing-edge-case": {
|
|
47988
49782
|
recall: 0,
|
|
47989
49783
|
fpRate: 0,
|
|
47990
49784
|
ratio: 0,
|
|
47991
49785
|
precision: 0,
|
|
47992
|
-
lastCalibratedAt: "2026-
|
|
49786
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
47993
49787
|
verdict: "DORMANT",
|
|
47994
|
-
|
|
47995
|
-
|
|
47996
|
-
|
|
49788
|
+
_calibrationNote: "v8.5 calibration (v0.18.9, 2026-07-01): rule did not fire on v8.5 corpus (252080 neg + 294178 pos = 546258 files). Preserved v7 data. v7 verdict=DORMANT, v7 lift=0, v7 recall=0, v7 FPR=0, v7 precision=0.",
|
|
49789
|
+
aiSpecific: true,
|
|
49790
|
+
_v7Verdict: "DORMANT",
|
|
49791
|
+
_v7Lift: 0,
|
|
49792
|
+
_v7Recall: 0,
|
|
49793
|
+
_v7FpRate: 0,
|
|
49794
|
+
_v7Precision: 0,
|
|
49795
|
+
_v8Verdict: "DORMANT",
|
|
49796
|
+
_v8Lift: 1,
|
|
49797
|
+
defaultOff: true
|
|
47997
49798
|
},
|
|
47998
|
-
"
|
|
49799
|
+
"test/weak-assertion": {
|
|
49800
|
+
recall: 0.0417,
|
|
49801
|
+
fpRate: 67e-4,
|
|
49802
|
+
ratio: 131.62,
|
|
49803
|
+
precision: 0.8793,
|
|
49804
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
49805
|
+
verdict: "USEFUL",
|
|
49806
|
+
_calibrationNote: "v8.5 calibration (v0.18.9, 2026-07-01): v7+v8 combined corpus (252080 neg + 294178 pos). v8.5 TP=12263, FP=1684, P=87.9%, FPR=0.67%, lift=131.62. v7 was USEFUL (TP=9906, FP=1583, lift=99.90). v8 was USEFUL (TP=2357, FP=101).",
|
|
49807
|
+
aiSpecific: true,
|
|
49808
|
+
_v7Verdict: "USEFUL",
|
|
49809
|
+
_v7Lift: 99.9,
|
|
49810
|
+
_v7Recall: 0.0418,
|
|
49811
|
+
_v7FpRate: 86e-4,
|
|
49812
|
+
_v7Precision: 0.8622,
|
|
49813
|
+
_v8Verdict: "USEFUL",
|
|
49814
|
+
_v8Lift: 651.94
|
|
49815
|
+
},
|
|
49816
|
+
"ts/enum-vs-as-const": {
|
|
47999
49817
|
recall: 0,
|
|
48000
49818
|
fpRate: 0,
|
|
48001
|
-
ratio:
|
|
49819
|
+
ratio: 1,
|
|
48002
49820
|
precision: 0,
|
|
48003
|
-
lastCalibratedAt: "2026-
|
|
49821
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
48004
49822
|
verdict: "DORMANT",
|
|
48005
|
-
|
|
48006
|
-
|
|
48007
|
-
|
|
49823
|
+
_calibrationNote: "v0.19: new rule (Uses `enum` \u2014 modern TS prefers `as const`). Not yet calibrated. Scheduled for v9 calibration.",
|
|
49824
|
+
aiSpecific: true,
|
|
49825
|
+
_v7Verdict: "DORMANT",
|
|
49826
|
+
_v7Lift: 1,
|
|
49827
|
+
_v7Recall: 0,
|
|
49828
|
+
_v7FpRate: 0,
|
|
49829
|
+
_v7Precision: 0,
|
|
49830
|
+
_v8Verdict: "DORMANT",
|
|
49831
|
+
_v8Lift: 1,
|
|
49832
|
+
defaultOff: true
|
|
48008
49833
|
},
|
|
48009
|
-
"
|
|
49834
|
+
"ts/excessive-type-assertion": {
|
|
48010
49835
|
recall: 0,
|
|
48011
49836
|
fpRate: 0,
|
|
48012
|
-
ratio:
|
|
49837
|
+
ratio: 1,
|
|
48013
49838
|
precision: 0,
|
|
48014
|
-
lastCalibratedAt: "2026-
|
|
49839
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
48015
49840
|
verdict: "DORMANT",
|
|
48016
|
-
|
|
48017
|
-
|
|
48018
|
-
|
|
49841
|
+
_calibrationNote: "v0.19: new rule (Function with >3 `as` assertions \u2014 AI fighting the type system). Not yet calibrated. Scheduled for v9 calibration.",
|
|
49842
|
+
aiSpecific: true,
|
|
49843
|
+
_v7Verdict: "DORMANT",
|
|
49844
|
+
_v7Lift: 1,
|
|
49845
|
+
_v7Recall: 0,
|
|
49846
|
+
_v7FpRate: 0,
|
|
49847
|
+
_v7Precision: 0,
|
|
49848
|
+
_v8Verdict: "DORMANT",
|
|
49849
|
+
_v8Lift: 1,
|
|
49850
|
+
defaultOff: true
|
|
48019
49851
|
},
|
|
48020
|
-
"
|
|
49852
|
+
"ts/import-type-misuse": {
|
|
48021
49853
|
recall: 0,
|
|
48022
49854
|
fpRate: 0,
|
|
48023
|
-
ratio:
|
|
49855
|
+
ratio: 1,
|
|
48024
49856
|
precision: 0,
|
|
48025
|
-
lastCalibratedAt: "2026-
|
|
49857
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
48026
49858
|
verdict: "DORMANT",
|
|
48027
|
-
|
|
48028
|
-
|
|
48029
|
-
|
|
49859
|
+
_calibrationNote: "v0.19: new rule (Inline `import { type X }` \u2014 prefer separate `import type`). Not yet calibrated. Scheduled for v9 calibration.",
|
|
49860
|
+
aiSpecific: true,
|
|
49861
|
+
_v7Verdict: "DORMANT",
|
|
49862
|
+
_v7Lift: 1,
|
|
49863
|
+
_v7Recall: 0,
|
|
49864
|
+
_v7FpRate: 0,
|
|
49865
|
+
_v7Precision: 0,
|
|
49866
|
+
_v8Verdict: "DORMANT",
|
|
49867
|
+
_v8Lift: 1,
|
|
49868
|
+
defaultOff: true
|
|
48030
49869
|
},
|
|
48031
|
-
"
|
|
49870
|
+
"ts/never-vs-unknown": {
|
|
48032
49871
|
recall: 0,
|
|
48033
49872
|
fpRate: 0,
|
|
48034
|
-
ratio:
|
|
49873
|
+
ratio: 1,
|
|
48035
49874
|
precision: 0,
|
|
48036
|
-
lastCalibratedAt: "2026-
|
|
49875
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
48037
49876
|
verdict: "DORMANT",
|
|
48038
|
-
|
|
48039
|
-
|
|
48040
|
-
|
|
49877
|
+
_calibrationNote: "v0.19: new rule (Return type `never` but body has no throw/loop/exit). Not yet calibrated. Scheduled for v9 calibration.",
|
|
49878
|
+
aiSpecific: true,
|
|
49879
|
+
_v7Verdict: "DORMANT",
|
|
49880
|
+
_v7Lift: 1,
|
|
49881
|
+
_v7Recall: 0,
|
|
49882
|
+
_v7FpRate: 0,
|
|
49883
|
+
_v7Precision: 0,
|
|
49884
|
+
_v8Verdict: "DORMANT",
|
|
49885
|
+
_v8Lift: 1,
|
|
49886
|
+
defaultOff: true
|
|
48041
49887
|
},
|
|
48042
|
-
"
|
|
49888
|
+
"ts/optional-chain-overuse": {
|
|
48043
49889
|
recall: 0,
|
|
48044
49890
|
fpRate: 0,
|
|
48045
|
-
ratio:
|
|
49891
|
+
ratio: 1,
|
|
48046
49892
|
precision: 0,
|
|
48047
|
-
lastCalibratedAt: "2026-
|
|
49893
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
48048
49894
|
verdict: "DORMANT",
|
|
48049
|
-
|
|
48050
|
-
|
|
48051
|
-
|
|
49895
|
+
_calibrationNote: "v0.19: new rule (Optional chain depth >= 5 \u2014 AI chains ?. rather than narrowing). Not yet calibrated. Scheduled for v9 calibration.",
|
|
49896
|
+
aiSpecific: true,
|
|
49897
|
+
_v7Verdict: "DORMANT",
|
|
49898
|
+
_v7Lift: 1,
|
|
49899
|
+
_v7Recall: 0,
|
|
49900
|
+
_v7FpRate: 0,
|
|
49901
|
+
_v7Precision: 0,
|
|
49902
|
+
_v8Verdict: "DORMANT",
|
|
49903
|
+
_v8Lift: 1,
|
|
49904
|
+
defaultOff: true
|
|
48052
49905
|
},
|
|
48053
|
-
"
|
|
49906
|
+
"typo/calc-fontsize": {
|
|
48054
49907
|
recall: 0,
|
|
48055
49908
|
fpRate: 0,
|
|
48056
49909
|
ratio: 0,
|
|
48057
49910
|
precision: 0,
|
|
48058
|
-
lastCalibratedAt: "2026-
|
|
49911
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
48059
49912
|
verdict: "DORMANT",
|
|
48060
|
-
|
|
48061
|
-
|
|
48062
|
-
|
|
49913
|
+
_calibrationNote: "v8.5 calibration (v0.18.9, 2026-07-01): rule did not fire on v8.5 corpus (252080 neg + 294178 pos = 546258 files). Preserved v7 data. v7 verdict=DORMANT, v7 lift=0, v7 recall=0, v7 FPR=0, v7 precision=0.",
|
|
49914
|
+
aiSpecific: false,
|
|
49915
|
+
_v7Verdict: "DORMANT",
|
|
49916
|
+
_v7Lift: 0,
|
|
49917
|
+
_v7Recall: 0,
|
|
49918
|
+
_v7FpRate: 0,
|
|
49919
|
+
_v7Precision: 0,
|
|
49920
|
+
_v8Verdict: "DORMANT",
|
|
49921
|
+
_v8Lift: 1,
|
|
49922
|
+
defaultOff: true
|
|
48063
49923
|
},
|
|
48064
|
-
"
|
|
49924
|
+
"typo/calc-raw-px": {
|
|
48065
49925
|
recall: 0,
|
|
48066
49926
|
fpRate: 0,
|
|
48067
|
-
ratio:
|
|
48068
|
-
precision: 0,
|
|
48069
|
-
lastCalibratedAt: "2026-
|
|
48070
|
-
verdict: "
|
|
48071
|
-
|
|
48072
|
-
|
|
48073
|
-
|
|
49927
|
+
ratio: 210066.67,
|
|
49928
|
+
precision: 0.8333,
|
|
49929
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
49930
|
+
verdict: "USEFUL",
|
|
49931
|
+
_calibrationNote: "v8.5 calibration (v0.18.9, 2026-07-01): v7+v8 combined corpus (252080 neg + 294178 pos). v8.5 TP=5, FP=1, P=83.3%, FPR=0.00%, lift=210066.67. v7 was USEFUL (TP=3, FP=1, lift=137559.75). v8 was USEFUL (TP=2, FP=0).",
|
|
49932
|
+
aiSpecific: false,
|
|
49933
|
+
_v7Verdict: "USEFUL",
|
|
49934
|
+
_v7Lift: 137559.75,
|
|
49935
|
+
_v7Recall: 0,
|
|
49936
|
+
_v7FpRate: 0,
|
|
49937
|
+
_v7Precision: 0.75,
|
|
49938
|
+
_v8Verdict: "USEFUL",
|
|
49939
|
+
_v8Lift: 99999
|
|
48074
49940
|
},
|
|
48075
|
-
"
|
|
49941
|
+
"typo/clamp-offscale": {
|
|
48076
49942
|
recall: 0,
|
|
48077
49943
|
fpRate: 0,
|
|
48078
49944
|
ratio: 0,
|
|
48079
49945
|
precision: 0,
|
|
48080
|
-
lastCalibratedAt: "2026-
|
|
49946
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
48081
49947
|
verdict: "DORMANT",
|
|
48082
|
-
|
|
48083
|
-
|
|
48084
|
-
|
|
49948
|
+
_calibrationNote: "v8.5 calibration (v0.18.9, 2026-07-01): rule did not fire on v8.5 corpus (252080 neg + 294178 pos = 546258 files). Preserved v7 data. v7 verdict=DORMANT, v7 lift=0, v7 recall=0, v7 FPR=0, v7 precision=0.",
|
|
49949
|
+
aiSpecific: false,
|
|
49950
|
+
_v7Verdict: "DORMANT",
|
|
49951
|
+
_v7Lift: 0,
|
|
49952
|
+
_v7Recall: 0,
|
|
49953
|
+
_v7FpRate: 0,
|
|
49954
|
+
_v7Precision: 0,
|
|
49955
|
+
_v8Verdict: "DORMANT",
|
|
49956
|
+
_v8Lift: 1,
|
|
49957
|
+
defaultOff: true
|
|
48085
49958
|
},
|
|
48086
|
-
"
|
|
49959
|
+
"typo/math-button-label-uniformity": {
|
|
49960
|
+
recall: 1e-4,
|
|
49961
|
+
fpRate: 1e-4,
|
|
49962
|
+
ratio: 6894.19,
|
|
49963
|
+
precision: 0.629,
|
|
49964
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
49965
|
+
verdict: "USEFUL",
|
|
49966
|
+
_calibrationNote: "v8.5 calibration (v0.18.9, 2026-07-01): v7+v8 combined corpus (252080 neg + 294178 pos). v8.5 TP=39, FP=23, P=62.9%, FPR=0.01%, lift=6894.19. v7 was USEFUL (TP=37, FP=21, lift=5571.66). v8 was USEFUL (TP=2, FP=2).",
|
|
49967
|
+
aiSpecific: false,
|
|
49968
|
+
_v7Verdict: "USEFUL",
|
|
49969
|
+
_v7Lift: 5571.66,
|
|
49970
|
+
_v7Recall: 2e-4,
|
|
49971
|
+
_v7FpRate: 1e-4,
|
|
49972
|
+
_v7Precision: 0.6379,
|
|
49973
|
+
_v8Verdict: "USEFUL",
|
|
49974
|
+
_v8Lift: 17166.75
|
|
49975
|
+
},
|
|
49976
|
+
"typo/math-cta-vocabulary": {
|
|
48087
49977
|
recall: 0,
|
|
48088
49978
|
fpRate: 0,
|
|
48089
49979
|
ratio: 0,
|
|
48090
49980
|
precision: 0,
|
|
48091
|
-
lastCalibratedAt: "2026-
|
|
49981
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
48092
49982
|
verdict: "DORMANT",
|
|
48093
|
-
|
|
48094
|
-
|
|
48095
|
-
|
|
49983
|
+
_calibrationNote: "v8.5 calibration (v0.18.9, 2026-07-01): rule did not fire on v8.5 corpus (252080 neg + 294178 pos = 546258 files). Preserved v7 data. v7 verdict=DORMANT, v7 lift=0, v7 recall=0, v7 FPR=0, v7 precision=0.",
|
|
49984
|
+
aiSpecific: true,
|
|
49985
|
+
_v7Verdict: "DORMANT",
|
|
49986
|
+
_v7Lift: 0,
|
|
49987
|
+
_v7Recall: 0,
|
|
49988
|
+
_v7FpRate: 0,
|
|
49989
|
+
_v7Precision: 0,
|
|
49990
|
+
_v8Verdict: "DORMANT",
|
|
49991
|
+
_v8Lift: 1,
|
|
49992
|
+
defaultOff: true
|
|
48096
49993
|
},
|
|
48097
|
-
"
|
|
48098
|
-
recall:
|
|
49994
|
+
"typo/placeholder-text": {
|
|
49995
|
+
recall: 1e-4,
|
|
48099
49996
|
fpRate: 0,
|
|
48100
|
-
ratio:
|
|
48101
|
-
precision: 0,
|
|
48102
|
-
lastCalibratedAt: "2026-
|
|
48103
|
-
verdict: "
|
|
48104
|
-
|
|
48105
|
-
|
|
48106
|
-
|
|
49997
|
+
ratio: 17330.5,
|
|
49998
|
+
precision: 0.6875,
|
|
49999
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
50000
|
+
verdict: "USEFUL",
|
|
50001
|
+
_calibrationNote: "v8.5 calibration (v0.18.9, 2026-07-01): v7+v8 combined corpus (252080 neg + 294178 pos). v8.5 TP=22, FP=10, P=68.8%, FPR=0.00%, lift=17330.50. v7 was DORMANT (TP=0, FP=0, lift=1.00). v8 was USEFUL (TP=22, FP=10).",
|
|
50002
|
+
aiSpecific: false,
|
|
50003
|
+
_v7Verdict: "DORMANT",
|
|
50004
|
+
_v7Lift: 1,
|
|
50005
|
+
_v7Recall: 0,
|
|
50006
|
+
_v7FpRate: 0,
|
|
50007
|
+
_v7Precision: 0,
|
|
50008
|
+
_v8Verdict: "USEFUL",
|
|
50009
|
+
_v8Lift: 4720.86
|
|
48107
50010
|
},
|
|
48108
|
-
"
|
|
50011
|
+
"visual/arbitrary-escape": {
|
|
50012
|
+
recall: 26e-4,
|
|
50013
|
+
fpRate: 7e-4,
|
|
50014
|
+
ratio: 1219.67,
|
|
50015
|
+
precision: 0.8177,
|
|
50016
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
50017
|
+
verdict: "USEFUL",
|
|
50018
|
+
_calibrationNote: "v8.5 calibration (v0.18.9, 2026-07-01): v7+v8 combined corpus (252080 neg + 294178 pos). v8.5 TP=758, FP=169, P=81.8%, FPR=0.07%, lift=1219.67. v7 was USEFUL (TP=600, FP=169, lift=846.78). v8 was USEFUL (TP=158, FP=0).",
|
|
50019
|
+
aiSpecific: true,
|
|
50020
|
+
_v7Verdict: "USEFUL",
|
|
50021
|
+
_v7Lift: 846.78,
|
|
50022
|
+
_v7Recall: 25e-4,
|
|
50023
|
+
_v7FpRate: 9e-4,
|
|
50024
|
+
_v7Precision: 0.7802,
|
|
50025
|
+
_v8Verdict: "USEFUL",
|
|
50026
|
+
_v8Lift: 99999
|
|
50027
|
+
},
|
|
50028
|
+
"visual/clamp-soup": {
|
|
48109
50029
|
recall: 0,
|
|
48110
50030
|
fpRate: 0,
|
|
48111
50031
|
ratio: 0,
|
|
48112
50032
|
precision: 0,
|
|
48113
|
-
lastCalibratedAt: "2026-
|
|
50033
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
48114
50034
|
verdict: "DORMANT",
|
|
48115
|
-
|
|
48116
|
-
|
|
48117
|
-
|
|
50035
|
+
_calibrationNote: "v8.5 calibration (v0.18.9, 2026-07-01): rule did not fire on v8.5 corpus (252080 neg + 294178 pos = 546258 files). Preserved v7 data. v7 verdict=DORMANT, v7 lift=0, v7 recall=0, v7 FPR=0, v7 precision=0.",
|
|
50036
|
+
aiSpecific: true,
|
|
50037
|
+
_v7Verdict: "DORMANT",
|
|
50038
|
+
_v7Lift: 0,
|
|
50039
|
+
_v7Recall: 0,
|
|
50040
|
+
_v7FpRate: 0,
|
|
50041
|
+
_v7Precision: 0,
|
|
50042
|
+
_v8Verdict: "DORMANT",
|
|
50043
|
+
_v8Lift: 1,
|
|
50044
|
+
defaultOff: true
|
|
48118
50045
|
},
|
|
48119
|
-
"
|
|
50046
|
+
"visual/generic-centering": {
|
|
48120
50047
|
recall: 0,
|
|
48121
50048
|
fpRate: 0,
|
|
48122
50049
|
ratio: 0,
|
|
48123
50050
|
precision: 0,
|
|
48124
|
-
lastCalibratedAt: "2026-
|
|
50051
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
48125
50052
|
verdict: "DORMANT",
|
|
48126
|
-
|
|
48127
|
-
|
|
48128
|
-
|
|
50053
|
+
_calibrationNote: "v8.5 calibration (v0.18.9, 2026-07-01): rule did not fire on v8.5 corpus (252080 neg + 294178 pos = 546258 files). Preserved v7 data. v7 verdict=DORMANT, v7 lift=0, v7 recall=0, v7 FPR=0, v7 precision=0.",
|
|
50054
|
+
aiSpecific: true,
|
|
50055
|
+
_v7Verdict: "DORMANT",
|
|
50056
|
+
_v7Lift: 0,
|
|
50057
|
+
_v7Recall: 0,
|
|
50058
|
+
_v7FpRate: 0,
|
|
50059
|
+
_v7Precision: 0,
|
|
50060
|
+
_v8Verdict: "DORMANT",
|
|
50061
|
+
_v8Lift: 1,
|
|
50062
|
+
defaultOff: true
|
|
48129
50063
|
},
|
|
48130
|
-
"
|
|
48131
|
-
recall: 0,
|
|
50064
|
+
"visual/inline-style-dominance": {
|
|
50065
|
+
recall: 0.0103,
|
|
50066
|
+
fpRate: 52e-4,
|
|
50067
|
+
ratio: 134.59,
|
|
50068
|
+
precision: 0.6983,
|
|
50069
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
50070
|
+
verdict: "USEFUL",
|
|
50071
|
+
_calibrationNote: "v8.5 calibration (v0.18.9, 2026-07-01): v7+v8 combined corpus (252080 neg + 294178 pos). v8.5 TP=3028, FP=1308, P=69.8%, FPR=0.52%, lift=134.59. v7 was USEFUL (TP=2303, FP=1221, lift=98.17). v8 was USEFUL (TP=725, FP=87).",
|
|
50072
|
+
aiSpecific: false,
|
|
50073
|
+
_v7Verdict: "USEFUL",
|
|
50074
|
+
_v7Lift: 98.17,
|
|
50075
|
+
_v7Recall: 97e-4,
|
|
50076
|
+
_v7FpRate: 67e-4,
|
|
50077
|
+
_v7Precision: 0.6535,
|
|
50078
|
+
_v8Verdict: "USEFUL",
|
|
50079
|
+
_v8Lift: 704.71
|
|
50080
|
+
},
|
|
50081
|
+
"visual/math-color-cluster": {
|
|
50082
|
+
recall: 2e-4,
|
|
48132
50083
|
fpRate: 0,
|
|
48133
|
-
ratio:
|
|
48134
|
-
precision: 0,
|
|
48135
|
-
lastCalibratedAt: "2026-
|
|
48136
|
-
verdict: "
|
|
48137
|
-
|
|
48138
|
-
|
|
48139
|
-
|
|
50084
|
+
ratio: 46814.86,
|
|
50085
|
+
precision: 0.9286,
|
|
50086
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
50087
|
+
verdict: "USEFUL",
|
|
50088
|
+
_calibrationNote: "v8.5 calibration (v0.18.9, 2026-07-01): v7+v8 combined corpus (252080 neg + 294178 pos). v8.5 TP=65, FP=5, P=92.9%, FPR=0.00%, lift=46814.86. v7 was USEFUL (TP=58, FP=5, lift=33771.28). v8 was USEFUL (TP=7, FP=0).",
|
|
50089
|
+
aiSpecific: true,
|
|
50090
|
+
_v7Verdict: "USEFUL",
|
|
50091
|
+
_v7Lift: 33771.28,
|
|
50092
|
+
_v7Recall: 2e-4,
|
|
50093
|
+
_v7FpRate: 0,
|
|
50094
|
+
_v7Precision: 0.9206,
|
|
50095
|
+
_v8Verdict: "USEFUL",
|
|
50096
|
+
_v8Lift: 99999
|
|
48140
50097
|
},
|
|
48141
|
-
"
|
|
50098
|
+
"visual/math-default-font": {
|
|
50099
|
+
recall: 16e-4,
|
|
50100
|
+
fpRate: 3e-4,
|
|
50101
|
+
ratio: 3035.16,
|
|
50102
|
+
precision: 0.8669,
|
|
50103
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
50104
|
+
verdict: "USEFUL",
|
|
50105
|
+
_calibrationNote: "v8.5 calibration (v0.18.9, 2026-07-01): v7+v8 combined corpus (252080 neg + 294178 pos). v8.5 TP=469, FP=72, P=86.7%, FPR=0.03%, lift=3035.16. v7 was USEFUL (TP=313, FP=71, lift=2105.64). v8 was USEFUL (TP=156, FP=1).",
|
|
50106
|
+
aiSpecific: true,
|
|
50107
|
+
_v7Verdict: "USEFUL",
|
|
50108
|
+
_v7Lift: 2105.64,
|
|
50109
|
+
_v7Recall: 13e-4,
|
|
50110
|
+
_v7FpRate: 4e-4,
|
|
50111
|
+
_v7Precision: 0.8151,
|
|
50112
|
+
_v8Verdict: "USEFUL",
|
|
50113
|
+
_v8Lift: 68229.63
|
|
50114
|
+
},
|
|
50115
|
+
"visual/math-font-entropy": {
|
|
50116
|
+
recall: 52e-4,
|
|
50117
|
+
fpRate: 1e-3,
|
|
50118
|
+
ratio: 869.95,
|
|
50119
|
+
precision: 0.8593,
|
|
50120
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
50121
|
+
verdict: "USEFUL",
|
|
50122
|
+
_calibrationNote: "v8.5 calibration (v0.18.9, 2026-07-01): v7+v8 combined corpus (252080 neg + 294178 pos). v8.5 TP=1521, FP=249, P=85.9%, FPR=0.10%, lift=869.95. v7 was USEFUL (TP=1067, FP=248, lift=600.09). v8 was USEFUL (TP=454, FP=1).",
|
|
50123
|
+
aiSpecific: true,
|
|
50124
|
+
_v7Verdict: "USEFUL",
|
|
50125
|
+
_v7Lift: 600.09,
|
|
50126
|
+
_v7Recall: 45e-4,
|
|
50127
|
+
_v7FpRate: 14e-4,
|
|
50128
|
+
_v7Precision: 0.8114,
|
|
50129
|
+
_v8Verdict: "USEFUL",
|
|
50130
|
+
_v8Lift: 68516.08
|
|
50131
|
+
},
|
|
50132
|
+
"visual/math-gradient-hue-rotation": {
|
|
48142
50133
|
recall: 0,
|
|
48143
50134
|
fpRate: 0,
|
|
48144
50135
|
ratio: 0,
|
|
48145
50136
|
precision: 0,
|
|
48146
|
-
lastCalibratedAt: "2026-
|
|
50137
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
48147
50138
|
verdict: "DORMANT",
|
|
48148
|
-
|
|
48149
|
-
|
|
48150
|
-
|
|
50139
|
+
_calibrationNote: "v8.5 calibration (v0.18.9, 2026-07-01): rule did not fire on v8.5 corpus (252080 neg + 294178 pos = 546258 files). Preserved v7 data. v7 verdict=DORMANT, v7 lift=0, v7 recall=0, v7 FPR=0, v7 precision=0.",
|
|
50140
|
+
aiSpecific: true,
|
|
50141
|
+
_v7Verdict: "DORMANT",
|
|
50142
|
+
_v7Lift: 0,
|
|
50143
|
+
_v7Recall: 0,
|
|
50144
|
+
_v7FpRate: 0,
|
|
50145
|
+
_v7Precision: 0,
|
|
50146
|
+
_v8Verdict: "DORMANT",
|
|
50147
|
+
_v8Lift: 1,
|
|
50148
|
+
defaultOff: true
|
|
48151
50149
|
},
|
|
48152
|
-
"
|
|
48153
|
-
recall:
|
|
50150
|
+
"visual/math-rounded-entropy": {
|
|
50151
|
+
recall: 38e-4,
|
|
50152
|
+
fpRate: 2e-4,
|
|
50153
|
+
ratio: 3785.45,
|
|
50154
|
+
precision: 0.9461,
|
|
50155
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
50156
|
+
verdict: "USEFUL",
|
|
50157
|
+
_calibrationNote: "v8.5 calibration (v0.18.9, 2026-07-01): v7+v8 combined corpus (252080 neg + 294178 pos). v8.5 TP=1105, FP=63, P=94.6%, FPR=0.02%, lift=3785.45. v7 was USEFUL (TP=876, FP=62, lift=2762.74). v8 was USEFUL (TP=229, FP=1).",
|
|
50158
|
+
aiSpecific: true,
|
|
50159
|
+
_v7Verdict: "USEFUL",
|
|
50160
|
+
_v7Lift: 2762.74,
|
|
50161
|
+
_v7Recall: 37e-4,
|
|
50162
|
+
_v7FpRate: 3e-4,
|
|
50163
|
+
_v7Precision: 0.9339,
|
|
50164
|
+
_v8Verdict: "USEFUL",
|
|
50165
|
+
_v8Lift: 68368.45
|
|
50166
|
+
},
|
|
50167
|
+
"visual/math-spacing-entropy": {
|
|
50168
|
+
recall: 18e-4,
|
|
50169
|
+
fpRate: 4e-4,
|
|
50170
|
+
ratio: 1898.99,
|
|
50171
|
+
precision: 0.8287,
|
|
50172
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
50173
|
+
verdict: "USEFUL",
|
|
50174
|
+
_calibrationNote: "v8.5 calibration (v0.18.9, 2026-07-01): v7+v8 combined corpus (252080 neg + 294178 pos). v8.5 TP=532, FP=110, P=82.9%, FPR=0.04%, lift=1898.99. v7 was USEFUL (TP=425, FP=109, lift=1339.22). v8 was USEFUL (TP=107, FP=1).",
|
|
50175
|
+
aiSpecific: true,
|
|
50176
|
+
_v7Verdict: "USEFUL",
|
|
50177
|
+
_v7Lift: 1339.22,
|
|
50178
|
+
_v7Recall: 18e-4,
|
|
50179
|
+
_v7FpRate: 6e-4,
|
|
50180
|
+
_v7Precision: 0.7959,
|
|
50181
|
+
_v8Verdict: "USEFUL",
|
|
50182
|
+
_v8Lift: 68031.19
|
|
50183
|
+
},
|
|
50184
|
+
"visual/naturalness-anomaly": {
|
|
50185
|
+
recall: 0.1729,
|
|
50186
|
+
fpRate: 0.0687,
|
|
50187
|
+
ratio: 10.86,
|
|
50188
|
+
precision: 0.746,
|
|
50189
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
50190
|
+
verdict: "USEFUL",
|
|
50191
|
+
_calibrationNote: "v8.5 calibration (v0.18.9, 2026-07-01): v7+v8 combined corpus (252080 neg + 294178 pos). v8.5 TP=50852, FP=17316, P=74.6%, FPR=6.87%, lift=10.86. v7 was USEFUL (TP=39319, FP=11382, lift=12.50). v8 was USEFUL (TP=11533, FP=5934).",
|
|
50192
|
+
aiSpecific: true,
|
|
50193
|
+
_v7Verdict: "USEFUL",
|
|
50194
|
+
_v7Lift: 12.5,
|
|
50195
|
+
_v7Recall: 0.1659,
|
|
50196
|
+
_v7FpRate: 0.0621,
|
|
50197
|
+
_v7Precision: 0.7755,
|
|
50198
|
+
_v8Verdict: "USEFUL",
|
|
50199
|
+
_v8Lift: 7.64
|
|
50200
|
+
},
|
|
50201
|
+
"visual/radius-scale-violation": {
|
|
50202
|
+
recall: 4e-4,
|
|
48154
50203
|
fpRate: 0,
|
|
48155
|
-
ratio:
|
|
48156
|
-
precision: 0,
|
|
48157
|
-
lastCalibratedAt: "2026-
|
|
48158
|
-
verdict: "
|
|
48159
|
-
defaultOff:
|
|
48160
|
-
|
|
48161
|
-
|
|
50204
|
+
ratio: 82131.33,
|
|
50205
|
+
precision: 0.9774,
|
|
50206
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
50207
|
+
verdict: "USEFUL",
|
|
50208
|
+
_calibrationNote: "v8.5 calibration (v0.18.9, 2026-07-01): v7+v8 combined corpus (252080 neg + 294178 pos). v8.5 TP=130, FP=3, P=97.7%, FPR=0.00%, lift=82131.33. v7 was USEFUL (TP=96, FP=3, lift=59285.01). v8 was USEFUL (TP=34, FP=0). v0.19 default-on (explicit defaultOff: false): P 97.7% / 82k lift \u2014 UI consistency.",
|
|
50209
|
+
aiSpecific: false,
|
|
50210
|
+
_v7Verdict: "USEFUL",
|
|
50211
|
+
_v7Lift: 59285.01,
|
|
50212
|
+
_v7Recall: 4e-4,
|
|
50213
|
+
_v7FpRate: 0,
|
|
50214
|
+
_v7Precision: 0.9697,
|
|
50215
|
+
_v8Verdict: "USEFUL",
|
|
50216
|
+
_v8Lift: 99999,
|
|
50217
|
+
defaultOff: false
|
|
48162
50218
|
},
|
|
48163
|
-
"
|
|
50219
|
+
"visual/spacing-scale-violation": {
|
|
50220
|
+
recall: 86e-4,
|
|
50221
|
+
fpRate: 28e-4,
|
|
50222
|
+
ratio: 273.97,
|
|
50223
|
+
precision: 0.7792,
|
|
50224
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
50225
|
+
verdict: "USEFUL",
|
|
50226
|
+
_calibrationNote: "v8.5 calibration (v0.18.9, 2026-07-01): v7+v8 combined corpus (252080 neg + 294178 pos). v8.5 TP=2531, FP=717, P=77.9%, FPR=0.28%, lift=273.97. v7 was USEFUL (TP=1981, FP=717, lift=187.83). v8 was USEFUL (TP=550, FP=0).",
|
|
50227
|
+
aiSpecific: false,
|
|
50228
|
+
_v7Verdict: "USEFUL",
|
|
50229
|
+
_v7Lift: 187.83,
|
|
50230
|
+
_v7Recall: 84e-4,
|
|
50231
|
+
_v7FpRate: 39e-4,
|
|
50232
|
+
_v7Precision: 0.7342,
|
|
50233
|
+
_v8Verdict: "USEFUL",
|
|
50234
|
+
_v8Lift: 99999
|
|
50235
|
+
},
|
|
50236
|
+
"wcag/dragging-movements": {
|
|
48164
50237
|
recall: 0,
|
|
48165
50238
|
fpRate: 0,
|
|
48166
|
-
ratio:
|
|
48167
|
-
precision: 0,
|
|
48168
|
-
lastCalibratedAt: "2026-
|
|
48169
|
-
verdict: "
|
|
48170
|
-
|
|
48171
|
-
|
|
48172
|
-
|
|
50239
|
+
ratio: 33610.67,
|
|
50240
|
+
precision: 0.4,
|
|
50241
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
50242
|
+
verdict: "OK",
|
|
50243
|
+
_calibrationNote: "v8.5 calibration (v0.18.9, 2026-07-01): v7+v8 combined corpus (252080 neg + 294178 pos). v8.5 TP=2, FP=3, P=40.0%, FPR=0.00%, lift=33610.67. v7 was OK (TP=2, FP=3, lift=24455.07). v8 was DORMANT (TP=0, FP=0).",
|
|
50244
|
+
aiSpecific: false,
|
|
50245
|
+
_v7Verdict: "OK",
|
|
50246
|
+
_v7Lift: 24455.07,
|
|
50247
|
+
_v7Recall: 0,
|
|
50248
|
+
_v7FpRate: 0,
|
|
50249
|
+
_v7Precision: 0.4,
|
|
50250
|
+
_v8Verdict: "DORMANT",
|
|
50251
|
+
_v8Lift: 1
|
|
48173
50252
|
},
|
|
48174
|
-
"
|
|
50253
|
+
"wcag/focus-appearance": {
|
|
50254
|
+
recall: 28e-4,
|
|
50255
|
+
fpRate: 1e-4,
|
|
50256
|
+
ratio: 8397.24,
|
|
50257
|
+
precision: 0.966,
|
|
50258
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
50259
|
+
verdict: "USEFUL",
|
|
50260
|
+
_calibrationNote: "v8.5 calibration (v0.18.9, 2026-07-01): v7+v8 combined corpus (252080 neg + 294178 pos). v8.5 TP=825, FP=29, P=96.6%, FPR=0.01%, lift=8397.24. v7 was USEFUL (TP=612, FP=24, lift=7353.82). v8 was USEFUL (TP=213, FP=5).",
|
|
50261
|
+
aiSpecific: false,
|
|
50262
|
+
_v7Verdict: "USEFUL",
|
|
50263
|
+
_v7Lift: 7353.82,
|
|
50264
|
+
_v7Recall: 26e-4,
|
|
50265
|
+
_v7FpRate: 1e-4,
|
|
50266
|
+
_v7Precision: 0.9623,
|
|
50267
|
+
_v8Verdict: "USEFUL",
|
|
50268
|
+
_v8Lift: 13418.41
|
|
50269
|
+
},
|
|
50270
|
+
"wcag/focus-obscured": {
|
|
50271
|
+
recall: 33e-4,
|
|
50272
|
+
fpRate: 7e-4,
|
|
50273
|
+
ratio: 1214.21,
|
|
50274
|
+
precision: 0.8478,
|
|
50275
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
50276
|
+
verdict: "USEFUL",
|
|
50277
|
+
_calibrationNote: "v8.5 calibration (v0.18.9, 2026-07-01): v7+v8 combined corpus (252080 neg + 294178 pos). v8.5 TP=980, FP=176, P=84.8%, FPR=0.07%, lift=1214.21. v7 was USEFUL (TP=797, FP=175, lift=859.38). v8 was USEFUL (TP=183, FP=1).",
|
|
50278
|
+
aiSpecific: false,
|
|
50279
|
+
_v7Verdict: "USEFUL",
|
|
50280
|
+
_v7Lift: 859.38,
|
|
50281
|
+
_v7Recall: 34e-4,
|
|
50282
|
+
_v7FpRate: 1e-3,
|
|
50283
|
+
_v7Precision: 0.82,
|
|
50284
|
+
_v8Verdict: "USEFUL",
|
|
50285
|
+
_v8Lift: 68293.81
|
|
50286
|
+
},
|
|
50287
|
+
"wcag/missing-alt": {
|
|
50288
|
+
recall: 11e-4,
|
|
50289
|
+
fpRate: 7e-4,
|
|
50290
|
+
ratio: 935.33,
|
|
50291
|
+
precision: 0.6456,
|
|
50292
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
50293
|
+
verdict: "USEFUL",
|
|
50294
|
+
_calibrationNote: "v8.5 calibration (v0.18.9, 2026-07-01): v7+v8 combined corpus (252080 neg + 294178 pos). v8.5 TP=317, FP=174, P=64.6%, FPR=0.07%, lift=935.33. v7 was DORMANT (TP=0, FP=0, lift=1.00). v8 was USEFUL (TP=317, FP=174).",
|
|
50295
|
+
aiSpecific: false,
|
|
50296
|
+
_v7Verdict: "DORMANT",
|
|
50297
|
+
_v7Lift: 1,
|
|
50298
|
+
_v7Recall: 0,
|
|
50299
|
+
_v7FpRate: 0,
|
|
50300
|
+
_v7Precision: 0,
|
|
50301
|
+
_v8Verdict: "USEFUL",
|
|
50302
|
+
_v8Lift: 254.79
|
|
50303
|
+
},
|
|
50304
|
+
"wcag/target-size": {
|
|
48175
50305
|
recall: 0,
|
|
48176
50306
|
fpRate: 0,
|
|
48177
50307
|
ratio: 0,
|
|
48178
50308
|
precision: 0,
|
|
48179
|
-
lastCalibratedAt: "2026-
|
|
50309
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
48180
50310
|
verdict: "DORMANT",
|
|
48181
|
-
|
|
48182
|
-
|
|
48183
|
-
|
|
50311
|
+
_calibrationNote: "v8.5 calibration (v0.18.9, 2026-07-01): rule did not fire on v8.5 corpus (252080 neg + 294178 pos = 546258 files). Preserved v7 data. v7 verdict=DORMANT, v7 lift=0, v7 recall=0, v7 FPR=0, v7 precision=0.",
|
|
50312
|
+
aiSpecific: false,
|
|
50313
|
+
_v7Verdict: "DORMANT",
|
|
50314
|
+
_v7Lift: 0,
|
|
50315
|
+
_v7Recall: 0,
|
|
50316
|
+
_v7FpRate: 0,
|
|
50317
|
+
_v7Precision: 0,
|
|
50318
|
+
_v8Verdict: "DORMANT",
|
|
50319
|
+
_v8Lift: 1,
|
|
50320
|
+
defaultOff: true
|
|
48184
50321
|
}
|
|
48185
50322
|
};
|
|
48186
50323
|
}
|
|
@@ -48247,7 +50384,6 @@ async function scanFile(filePath, config, registry, cwd = process.cwd()) {
|
|
|
48247
50384
|
".kt",
|
|
48248
50385
|
".kts",
|
|
48249
50386
|
".dart",
|
|
48250
|
-
".rs",
|
|
48251
50387
|
".cpp",
|
|
48252
50388
|
".cc",
|
|
48253
50389
|
".cxx",
|
|
@@ -55155,7 +57291,24 @@ var RULE_HINTS = {
|
|
|
55155
57291
|
"docs/stale-package-reference": "Update the doc to reference an installed package, or add the package to package.json. Copy-pasted install commands from a previous project are the #1 doc-drift failure mode.",
|
|
55156
57292
|
"docs/stale-function-reference": "Rename the doc reference to match a current export, or add a wrapper export. Stale function callouts in tutorials cost readers 10+ minutes of debugging.",
|
|
55157
57293
|
"docs/expired-code-example": "Update the example to use a declared dependency, or add the package to package.json. A copy-pasteable example that does not install erodes trust in the whole docs site.",
|
|
55158
|
-
"docs/broken-link": "Create the file or fix the link target. On a public docs site, broken links erode trust more than stale copy."
|
|
57294
|
+
"docs/broken-link": "Create the file or fix the link target. On a public docs site, broken links erode trust more than stale copy.",
|
|
57295
|
+
// v0.18.9 — Rust-specific rules (tree-sitter-backed)
|
|
57296
|
+
"rust/unused-pub-fn": "Remove the function or call it. Rust's compiler doesn't warn on `pub fn` references unless `#![warn(dead_code)]` is set at the crate root. AI agents leave these behind during iterative refactors.",
|
|
57297
|
+
"rust/unwrap-in-production": "Replace `.unwrap()` / `.expect()` with `?` (early-return on Err), `.map_err(...)` for error conversion, or an explicit `match`. They panic in production; reserve them for `#[cfg(test)]` or `#[test]` scopes.",
|
|
57298
|
+
"rust/todo-macro": "Implement the function body or remove the stub. `todo!()` / `unimplemented!()` both expand to `panic!()`, so a hit at runtime crashes the program. Move them into a `#[cfg(test)] mod tests` block to suppress.",
|
|
57299
|
+
"rust/stringly-typed": 'Replace the `String` / `&str` parameter with the typed enum that already exists in the file. Stringly-typed APIs lose type information at the boundary \u2014 typos (`"Click"` vs `"click"`) only fail at runtime.',
|
|
57300
|
+
// v0.19.0 — TypeScript-specific rules
|
|
57301
|
+
"ts/optional-chain-overuse": "Break long `?.` chains with an intermediate variable or guard clause (`if (!value) return;`). Long chains hide the type-narrowing that should be explicit. AI agents chain `?.` to avoid null checks.",
|
|
57302
|
+
"ts/enum-vs-as-const": "Replace `enum Foo { A, B }` with `const Foo = { A: 'A', B: 'B' } as const` (or `const Foo = ['A', 'B'] as const`). Modern TS style guides (Google, TS-eslint) prefer `as const` because enums have surprising runtime semantics.",
|
|
57303
|
+
"ts/import-type-misuse": "Use `import type { X } from '...'` instead of `import { type X } from '...'`. The split form is more common in real codebases and makes the type-only intent unambiguous.",
|
|
57304
|
+
"ts/never-vs-unknown": "The `never` return type means 'this function never returns'. Reserve it for functions that always throw, always loop, or always exit. For 'impossible' branches, use a concrete type (`void`, `Error`, `unknown`) and an exhaustive check.",
|
|
57305
|
+
"ts/excessive-type-assertion": "More than 3 `as` assertions in one function is a strong signal that the type is wrong, not the code. Fix the type definition (or use a type guard) instead of bypassing the type system.",
|
|
57306
|
+
// v0.19.0 — Go-specific rules
|
|
57307
|
+
"go/error-wrap-without-context": 'Use `fmt.Errorf("opening config: %w", err)` not `fmt.Errorf("error: %w", err)`. Real Go errors include the failing operation. See golang.org/wiki/CodeReviewComments#error-strings.',
|
|
57308
|
+
"go/struct-tag-inconsistency": 'Pick one tag style per struct. If most fields are `json:"foo"`, this field should be too. Real Go code maintains consistency within a struct (or within a package).',
|
|
57309
|
+
"go/nil-slice-vs-empty": "Either declare as `var x = []int{}` or assign with `make([]int, 0)`. The nil/empty inconsistency is an AI signal \u2014 real code picks one form and sticks with it.",
|
|
57310
|
+
// v0.19.0 — Duplication detector
|
|
57311
|
+
"dup/identical-block": "Refactor to a shared helper. This is a Type-1 clone (byte-for-byte identical after normalization). Common in AI-generated code that copy-pastes from training data."
|
|
55159
57312
|
};
|
|
55160
57313
|
|
|
55161
57314
|
// src/cli/commands/explain.ts
|