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.js
CHANGED
|
@@ -19,7 +19,7 @@ var VERSION;
|
|
|
19
19
|
var init_header = __esm({
|
|
20
20
|
"src/types/_header.ts"() {
|
|
21
21
|
"use strict";
|
|
22
|
-
VERSION = "0.
|
|
22
|
+
VERSION = "0.19.0";
|
|
23
23
|
}
|
|
24
24
|
});
|
|
25
25
|
|
|
@@ -28220,6 +28220,20 @@ var init_unreachable = __esm({
|
|
|
28220
28220
|
});
|
|
28221
28221
|
|
|
28222
28222
|
// src/rules/dead/unused-import.ts
|
|
28223
|
+
function collectRustReferencedNames(source) {
|
|
28224
|
+
const out = /* @__PURE__ */ new Set();
|
|
28225
|
+
for (const m of source.matchAll(/\b([A-Za-z_][A-Za-z0-9_]*)\b/g)) {
|
|
28226
|
+
out.add(m[1]);
|
|
28227
|
+
}
|
|
28228
|
+
return out;
|
|
28229
|
+
}
|
|
28230
|
+
function stripUseDeclarations(source) {
|
|
28231
|
+
let out = source;
|
|
28232
|
+
out = out.replace(/^\s*use\s+[\s\S]*?;\s*$/gm, "");
|
|
28233
|
+
out = out.replace(/\/\/[^\n]*/g, "");
|
|
28234
|
+
out = out.replace(/\/\*[\s\S]*?\*\//g, "");
|
|
28235
|
+
return out;
|
|
28236
|
+
}
|
|
28223
28237
|
var unusedImportRule;
|
|
28224
28238
|
var init_unused_import = __esm({
|
|
28225
28239
|
"src/rules/dead/unused-import.ts"() {
|
|
@@ -28255,6 +28269,26 @@ var init_unused_import = __esm({
|
|
|
28255
28269
|
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.`
|
|
28256
28270
|
});
|
|
28257
28271
|
}
|
|
28272
|
+
if (facts.v2.rustFile) {
|
|
28273
|
+
const strippedSource = stripUseDeclarations(facts.v2._source ?? "");
|
|
28274
|
+
const referenced = collectRustReferencedNames(strippedSource);
|
|
28275
|
+
for (const imp of facts.v2.rustFile.imports) {
|
|
28276
|
+
for (const nameEntry of imp.names) {
|
|
28277
|
+
if (referenced.has(nameEntry.name)) continue;
|
|
28278
|
+
const source = ` from '${imp.path}'`;
|
|
28279
|
+
issues.push({
|
|
28280
|
+
ruleId: "dead/unused-import",
|
|
28281
|
+
category: "logic",
|
|
28282
|
+
severity: "low",
|
|
28283
|
+
aiSpecific: true,
|
|
28284
|
+
message: `Unused import: '${nameEntry.name}'${source}`,
|
|
28285
|
+
line: imp.line,
|
|
28286
|
+
column: imp.column,
|
|
28287
|
+
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)].`
|
|
28288
|
+
});
|
|
28289
|
+
}
|
|
28290
|
+
}
|
|
28291
|
+
}
|
|
28258
28292
|
return issues;
|
|
28259
28293
|
}
|
|
28260
28294
|
});
|
|
@@ -28997,10 +29031,67 @@ var init_dart = __esm({
|
|
|
28997
29031
|
}
|
|
28998
29032
|
});
|
|
28999
29033
|
|
|
29034
|
+
// src/engine/parser-rust.ts
|
|
29035
|
+
import Parser from "tree-sitter";
|
|
29036
|
+
import Rust from "tree-sitter-rust";
|
|
29037
|
+
function getRustParser() {
|
|
29038
|
+
if (cachedParser) return { ok: true, parser: cachedParser };
|
|
29039
|
+
if (loadError) return { ok: false, error: loadError };
|
|
29040
|
+
try {
|
|
29041
|
+
rustLanguage = Rust;
|
|
29042
|
+
if (!rustLanguage || typeof rustLanguage !== "object") {
|
|
29043
|
+
throw new Error("tree-sitter-rust: language export is missing or malformed");
|
|
29044
|
+
}
|
|
29045
|
+
const parser = new Parser();
|
|
29046
|
+
parser.setLanguage(rustLanguage);
|
|
29047
|
+
cachedParser = parser;
|
|
29048
|
+
return { ok: true, parser };
|
|
29049
|
+
} catch (err) {
|
|
29050
|
+
loadError = err instanceof Error ? err : new Error(String(err));
|
|
29051
|
+
return { ok: false, error: loadError };
|
|
29052
|
+
}
|
|
29053
|
+
}
|
|
29054
|
+
function effectiveParser() {
|
|
29055
|
+
if (forcedFailure) return { ok: false, error: forcedFailure };
|
|
29056
|
+
return getRustParser();
|
|
29057
|
+
}
|
|
29058
|
+
function parseRust(source) {
|
|
29059
|
+
const result = effectiveParser();
|
|
29060
|
+
if (!result.ok) return null;
|
|
29061
|
+
if (!source || source.trim() === "") return null;
|
|
29062
|
+
try {
|
|
29063
|
+
const rawTree = result.parser.parse(source);
|
|
29064
|
+
if (!rawTree) return null;
|
|
29065
|
+
const tree = rawTree;
|
|
29066
|
+
if (!tree || !tree.rootNode) return null;
|
|
29067
|
+
if (tree.rootNode.type === "ERROR" && tree.rootNode.childCount === 0) {
|
|
29068
|
+
return null;
|
|
29069
|
+
}
|
|
29070
|
+
return tree;
|
|
29071
|
+
} catch {
|
|
29072
|
+
return null;
|
|
29073
|
+
}
|
|
29074
|
+
}
|
|
29075
|
+
function isRustParserAvailable() {
|
|
29076
|
+
const result = getRustParser();
|
|
29077
|
+
return result.ok;
|
|
29078
|
+
}
|
|
29079
|
+
var cachedParser, rustLanguage, loadError, forcedFailure;
|
|
29080
|
+
var init_parser_rust = __esm({
|
|
29081
|
+
"src/engine/parser-rust.ts"() {
|
|
29082
|
+
"use strict";
|
|
29083
|
+
cachedParser = null;
|
|
29084
|
+
rustLanguage = null;
|
|
29085
|
+
loadError = null;
|
|
29086
|
+
forcedFailure = null;
|
|
29087
|
+
}
|
|
29088
|
+
});
|
|
29089
|
+
|
|
29000
29090
|
// src/engine/visitors/rust.ts
|
|
29001
29091
|
var rust_exports = {};
|
|
29002
29092
|
__export(rust_exports, {
|
|
29003
|
-
extractRustPatterns: () => extractRustPatterns
|
|
29093
|
+
extractRustPatterns: () => extractRustPatterns,
|
|
29094
|
+
parseRustFile: () => parseRustFile
|
|
29004
29095
|
});
|
|
29005
29096
|
function extractRustPatterns(filePath, source) {
|
|
29006
29097
|
const service = [];
|
|
@@ -29053,188 +29144,487 @@ function extractRustPatterns(filePath, source) {
|
|
|
29053
29144
|
}
|
|
29054
29145
|
return { service, route, ormModel };
|
|
29055
29146
|
}
|
|
29056
|
-
|
|
29057
|
-
|
|
29058
|
-
|
|
29059
|
-
|
|
29060
|
-
|
|
29061
|
-
|
|
29062
|
-
|
|
29063
|
-
|
|
29064
|
-
|
|
29065
|
-
|
|
29066
|
-
"Helper",
|
|
29067
|
-
"Factory",
|
|
29068
|
-
"Provider",
|
|
29069
|
-
"Store",
|
|
29070
|
-
"API",
|
|
29071
|
-
"Client",
|
|
29072
|
-
"Adapter",
|
|
29073
|
-
"Resolver",
|
|
29074
|
-
"Mapper",
|
|
29075
|
-
"Transformer",
|
|
29076
|
-
"Serializer",
|
|
29077
|
-
"Validator",
|
|
29078
|
-
"Strategy",
|
|
29079
|
-
"Facade",
|
|
29080
|
-
"Decorator",
|
|
29081
|
-
"Observer",
|
|
29082
|
-
"Builder",
|
|
29083
|
-
"Command",
|
|
29084
|
-
"Processor",
|
|
29085
|
-
"Worker",
|
|
29086
|
-
"Job",
|
|
29087
|
-
"Actor",
|
|
29088
|
-
"Executor"
|
|
29089
|
-
];
|
|
29090
|
-
SERVICE_SUFFIX_GROUP4 = `(?:${SERVICE_SUFFIXES4.join("|")})`;
|
|
29091
|
-
RUST_SERVICE_STRUCT_RE = new RegExp(
|
|
29092
|
-
`^(?:pub(?:\\(crate\\)|\\(super\\))?\\s+)?struct\\s+(\\w+?)${SERVICE_SUFFIX_GROUP4}?\\b`,
|
|
29093
|
-
"gm"
|
|
29094
|
-
);
|
|
29095
|
-
RUST_SERVICE_IMPL_RE = new RegExp(
|
|
29096
|
-
`^impl(?:<[^>]+>)?\\s+(?:${SERVICE_SUFFIX_GROUP4}\\s+for\\s+)?(\\w+?)${SERVICE_SUFFIX_GROUP4}?\\b`,
|
|
29097
|
-
"gm"
|
|
29098
|
-
);
|
|
29099
|
-
RUST_ACTIX_ROUTE_RE = /#\[(?:get|post|put|delete|patch|head|route)\(\s*"(\/[^"]+)"\s*[\),]/g;
|
|
29100
|
-
RUST_AXUM_ROUTE_RE = /\.route\(\s*"(\/[^"]+)"\s*,\s*(?:get|post|put|delete|patch)/g;
|
|
29101
|
-
RUST_DIESEL_RE = /#\[derive\([^\]]*Queryable[^\]]*\)\][\s\S]{0,200}?struct\s+(\w+)/g;
|
|
29102
|
-
RUST_SEAORM_RE = /#\[derive\([^\]]*DeriveEntityModel[^\]]*\)\][\s\S]{0,200}?struct\s+(\w+)/g;
|
|
29103
|
-
RUST_SQLX_RE = /#\[derive\([^\]]*sqlx::FromRow[^\]]*\)\][\s\S]{0,200}?struct\s+(\w+)/g;
|
|
29147
|
+
function parseRustFile(filePath, source, options = {}) {
|
|
29148
|
+
const empty = {
|
|
29149
|
+
imports: [],
|
|
29150
|
+
functions: [],
|
|
29151
|
+
structs: [],
|
|
29152
|
+
traits: [],
|
|
29153
|
+
impls: []
|
|
29154
|
+
};
|
|
29155
|
+
if (!isRustParserAvailable() || options.forceFallback) {
|
|
29156
|
+
return empty;
|
|
29104
29157
|
}
|
|
29105
|
-
|
|
29106
|
-
|
|
29107
|
-
|
|
29108
|
-
|
|
29109
|
-
|
|
29110
|
-
|
|
29111
|
-
|
|
29112
|
-
|
|
29113
|
-
|
|
29114
|
-
|
|
29115
|
-
|
|
29116
|
-
|
|
29117
|
-
|
|
29118
|
-
|
|
29119
|
-
|
|
29120
|
-
|
|
29121
|
-
|
|
29158
|
+
const tree = parseRust(source);
|
|
29159
|
+
if (!tree) return empty;
|
|
29160
|
+
return walkRustTree(tree);
|
|
29161
|
+
}
|
|
29162
|
+
function walkRustTree(tree) {
|
|
29163
|
+
const ctx = { inTestConfig: false };
|
|
29164
|
+
const out = {
|
|
29165
|
+
imports: [],
|
|
29166
|
+
functions: [],
|
|
29167
|
+
structs: [],
|
|
29168
|
+
traits: [],
|
|
29169
|
+
impls: []
|
|
29170
|
+
};
|
|
29171
|
+
walkChildren(tree.rootNode, ctx, out);
|
|
29172
|
+
return out;
|
|
29173
|
+
}
|
|
29174
|
+
function walkChildren(node, ctx, out) {
|
|
29175
|
+
for (let i = 0; i < node.namedChildCount; i++) {
|
|
29176
|
+
const child = node.namedChild(i);
|
|
29177
|
+
if (!child) continue;
|
|
29178
|
+
visitNode(child, ctx, out);
|
|
29122
29179
|
}
|
|
29123
|
-
|
|
29124
|
-
|
|
29125
|
-
|
|
29126
|
-
|
|
29127
|
-
|
|
29128
|
-
|
|
29180
|
+
}
|
|
29181
|
+
function visitNode(node, ctx, out) {
|
|
29182
|
+
const innerCtx = { ...ctx };
|
|
29183
|
+
const attrState = readPrecedingAttributes(node);
|
|
29184
|
+
switch (node.type) {
|
|
29185
|
+
case "use_declaration": {
|
|
29186
|
+
out.imports.push(extractUse(node));
|
|
29187
|
+
return;
|
|
29188
|
+
}
|
|
29189
|
+
case "function_item": {
|
|
29190
|
+
const isMethod = isInImplBlock(node);
|
|
29191
|
+
out.functions.push(extractFunction(node, attrState, innerCtx.inTestConfig, isMethod));
|
|
29192
|
+
walkChildren(getField(node, "body") ?? node, innerCtx, out);
|
|
29193
|
+
return;
|
|
29194
|
+
}
|
|
29195
|
+
case "struct_item": {
|
|
29196
|
+
out.structs.push(extractStruct(node, attrState));
|
|
29197
|
+
const body = getField(node, "body");
|
|
29198
|
+
if (body) walkChildren(body, innerCtx, out);
|
|
29199
|
+
return;
|
|
29200
|
+
}
|
|
29201
|
+
case "trait_item": {
|
|
29202
|
+
out.traits.push(extractTrait(node, attrState));
|
|
29203
|
+
const body = getField(node, "body");
|
|
29204
|
+
if (body) walkChildren(body, innerCtx, out);
|
|
29205
|
+
return;
|
|
29206
|
+
}
|
|
29207
|
+
case "impl_item": {
|
|
29208
|
+
const implEntry = extractImpl(node, attrState, innerCtx);
|
|
29209
|
+
out.impls.push(implEntry.entry);
|
|
29210
|
+
const body = getField(node, "body");
|
|
29211
|
+
if (body) walkChildren(body, innerCtx, out);
|
|
29212
|
+
return;
|
|
29213
|
+
}
|
|
29214
|
+
case "mod_item": {
|
|
29215
|
+
const modIsTest = innerCtx.inTestConfig || attrState.isTestCfg;
|
|
29216
|
+
const modCtx = { ...innerCtx, inTestConfig: modIsTest };
|
|
29217
|
+
const body = getField(node, "body");
|
|
29218
|
+
if (body) walkChildren(body, modCtx, out);
|
|
29219
|
+
return;
|
|
29220
|
+
}
|
|
29221
|
+
default: {
|
|
29222
|
+
for (let i = 0; i < node.namedChildCount; i++) {
|
|
29223
|
+
const child = node.namedChild(i);
|
|
29224
|
+
if (child) visitNode(child, innerCtx, out);
|
|
29225
|
+
}
|
|
29226
|
+
}
|
|
29129
29227
|
}
|
|
29130
|
-
|
|
29131
|
-
|
|
29228
|
+
}
|
|
29229
|
+
function readPrecedingAttributes(node) {
|
|
29230
|
+
const state = {
|
|
29231
|
+
isTestCfg: false,
|
|
29232
|
+
isTest: false,
|
|
29233
|
+
isPub: false,
|
|
29234
|
+
derives: []
|
|
29235
|
+
};
|
|
29236
|
+
const parent = node.parent;
|
|
29237
|
+
if (!parent) return state;
|
|
29238
|
+
for (let i = 0; i < parent.namedChildCount; i++) {
|
|
29239
|
+
const sibling = parent.namedChild(i);
|
|
29240
|
+
if (!sibling || sibling === node) continue;
|
|
29241
|
+
if (sibling.endIndex > node.startIndex) continue;
|
|
29242
|
+
if (sibling.type !== "attribute_item") continue;
|
|
29243
|
+
decodeAttribute(sibling, state);
|
|
29244
|
+
}
|
|
29245
|
+
return state;
|
|
29246
|
+
}
|
|
29247
|
+
function decodeAttribute(attr, state) {
|
|
29248
|
+
for (let i = 0; i < attr.namedChildCount; i++) {
|
|
29249
|
+
const child = attr.namedChild(i);
|
|
29250
|
+
if (!child || child.type !== "attribute") continue;
|
|
29251
|
+
const name = firstIdentifier(child);
|
|
29132
29252
|
if (!name) continue;
|
|
29133
|
-
if (
|
|
29134
|
-
|
|
29135
|
-
|
|
29136
|
-
|
|
29137
|
-
|
|
29138
|
-
|
|
29139
|
-
|
|
29140
|
-
|
|
29141
|
-
|
|
29253
|
+
if (name === "cfg") {
|
|
29254
|
+
const cfgText = child.text;
|
|
29255
|
+
if (/\btest\b/.test(cfgText) && !/\bnot\(test\)/.test(cfgText)) {
|
|
29256
|
+
state.isTestCfg = true;
|
|
29257
|
+
}
|
|
29258
|
+
} else if (name === "test") {
|
|
29259
|
+
state.isTest = true;
|
|
29260
|
+
} else if (name === "derive") {
|
|
29261
|
+
for (let j = 0; j < child.namedChildCount; j++) {
|
|
29262
|
+
const inner = child.namedChild(j);
|
|
29263
|
+
if (inner) {
|
|
29264
|
+
const matches = inner.text.matchAll(/\b([A-Z][A-Za-z0-9_]*)\b/g);
|
|
29265
|
+
for (const m of matches) state.derives.push(m[1]);
|
|
29266
|
+
}
|
|
29267
|
+
}
|
|
29268
|
+
}
|
|
29142
29269
|
}
|
|
29143
|
-
return { service, route, ormModel };
|
|
29144
29270
|
}
|
|
29145
|
-
|
|
29146
|
-
|
|
29147
|
-
|
|
29148
|
-
|
|
29149
|
-
|
|
29150
|
-
|
|
29151
|
-
|
|
29152
|
-
|
|
29153
|
-
|
|
29154
|
-
|
|
29155
|
-
|
|
29156
|
-
|
|
29157
|
-
|
|
29158
|
-
|
|
29159
|
-
|
|
29160
|
-
|
|
29161
|
-
"
|
|
29162
|
-
|
|
29163
|
-
"
|
|
29164
|
-
|
|
29165
|
-
"
|
|
29166
|
-
|
|
29167
|
-
|
|
29168
|
-
|
|
29169
|
-
|
|
29170
|
-
|
|
29171
|
-
|
|
29172
|
-
|
|
29173
|
-
"
|
|
29174
|
-
|
|
29175
|
-
|
|
29176
|
-
|
|
29177
|
-
|
|
29178
|
-
|
|
29179
|
-
|
|
29180
|
-
|
|
29181
|
-
|
|
29182
|
-
|
|
29183
|
-
|
|
29184
|
-
|
|
29271
|
+
function firstIdentifier(node) {
|
|
29272
|
+
const text = node.text;
|
|
29273
|
+
const idMatch = text.match(/^([a-zA-Z_][a-zA-Z0-9_]*)/);
|
|
29274
|
+
return idMatch ? idMatch[1] : null;
|
|
29275
|
+
}
|
|
29276
|
+
function extractUse(node) {
|
|
29277
|
+
const text = node.text;
|
|
29278
|
+
const argument = node.namedChild(0);
|
|
29279
|
+
const argField = node.childForFieldName("argument");
|
|
29280
|
+
const path = argField?.text ?? argument?.text ?? "";
|
|
29281
|
+
const names = [];
|
|
29282
|
+
let isGlob = false;
|
|
29283
|
+
const useListNode = findUseListNode(argument);
|
|
29284
|
+
if (useListNode) {
|
|
29285
|
+
for (let i = 0; i < useListNode.namedChildCount; i++) {
|
|
29286
|
+
const item = useListNode.namedChild(i);
|
|
29287
|
+
if (item.type === "use_wildcard") {
|
|
29288
|
+
isGlob = true;
|
|
29289
|
+
} else if (item.type === "identifier") {
|
|
29290
|
+
names.push({ name: item.text });
|
|
29291
|
+
} else if (item.type === "use_as_clause") {
|
|
29292
|
+
const alias = item.childForFieldName("alias");
|
|
29293
|
+
const binding = item.childForFieldName("path");
|
|
29294
|
+
if (binding) {
|
|
29295
|
+
names.push({ name: binding.text, alias: alias?.text });
|
|
29296
|
+
} else {
|
|
29297
|
+
names.push({ name: item.text });
|
|
29298
|
+
}
|
|
29299
|
+
} else if (item.type === "scoped_identifier") {
|
|
29300
|
+
const idents = collectIdentifiers(item);
|
|
29301
|
+
names.push({ name: idents[idents.length - 1] ?? item.text });
|
|
29302
|
+
} else if (item.text.includes(" as ")) {
|
|
29303
|
+
const [head, alias] = item.text.split(/\s+as\s+/);
|
|
29304
|
+
names.push({ name: (head ?? "").trim(), alias: alias?.trim() });
|
|
29305
|
+
} else {
|
|
29306
|
+
names.push({ name: item.text });
|
|
29307
|
+
}
|
|
29308
|
+
}
|
|
29309
|
+
} else if (argument?.type === "use_wildcard") {
|
|
29310
|
+
isGlob = true;
|
|
29311
|
+
} else if (argument) {
|
|
29312
|
+
const idents = collectIdentifiers(argument);
|
|
29313
|
+
const last = idents[idents.length - 1] ?? argument.text;
|
|
29314
|
+
names.push({ name: last });
|
|
29315
|
+
const asMatch = text.match(/\s+as\s+(\w+)\s*;?\s*$/);
|
|
29316
|
+
if (asMatch) names[0].alias = asMatch[1];
|
|
29185
29317
|
}
|
|
29186
|
-
|
|
29187
|
-
|
|
29188
|
-
|
|
29189
|
-
|
|
29190
|
-
|
|
29191
|
-
|
|
29192
|
-
}
|
|
29193
|
-
|
|
29194
|
-
|
|
29195
|
-
const
|
|
29196
|
-
const
|
|
29197
|
-
const
|
|
29198
|
-
|
|
29199
|
-
|
|
29200
|
-
|
|
29201
|
-
|
|
29202
|
-
|
|
29318
|
+
return {
|
|
29319
|
+
path: path.trim(),
|
|
29320
|
+
names,
|
|
29321
|
+
isGlob,
|
|
29322
|
+
line: node.startPosition.row + 1,
|
|
29323
|
+
column: node.startPosition.column
|
|
29324
|
+
};
|
|
29325
|
+
}
|
|
29326
|
+
function extractFunction(node, attrs, inheritedTestConfig, isMethod) {
|
|
29327
|
+
const nameNode = node.childForFieldName("name");
|
|
29328
|
+
const name = nameNode?.text ?? "<anon>";
|
|
29329
|
+
const params = node.childForFieldName("parameters");
|
|
29330
|
+
const body = node.childForFieldName("body");
|
|
29331
|
+
const visibilityMod = node.namedChild(0);
|
|
29332
|
+
const isPublic = visibilityMod?.type === "visibility_modifier";
|
|
29333
|
+
let receiver;
|
|
29334
|
+
if (isMethod && params) {
|
|
29335
|
+
const selfParam = findSelfParameter(params);
|
|
29336
|
+
if (selfParam) receiver = selfParam.text;
|
|
29337
|
+
}
|
|
29338
|
+
const bodyLines = body ? body.endPosition.row - body.startPosition.row + 1 : 0;
|
|
29339
|
+
const inTestConfig = inheritedTestConfig || attrs.isTest || attrs.isTestCfg || isFunctionAttrTest(node);
|
|
29340
|
+
return {
|
|
29341
|
+
name,
|
|
29342
|
+
line: node.startPosition.row + 1,
|
|
29343
|
+
column: node.startPosition.column,
|
|
29344
|
+
isPublic,
|
|
29345
|
+
isMethod,
|
|
29346
|
+
receiver,
|
|
29347
|
+
bodyLines,
|
|
29348
|
+
inTestConfig
|
|
29349
|
+
};
|
|
29350
|
+
}
|
|
29351
|
+
function extractStruct(node, attrs) {
|
|
29352
|
+
const nameNode = node.childForFieldName("name");
|
|
29353
|
+
return {
|
|
29354
|
+
name: nameNode?.text ?? "<anon>",
|
|
29355
|
+
line: node.startPosition.row + 1,
|
|
29356
|
+
column: node.startPosition.column,
|
|
29357
|
+
isPublic: hasVisibility(node),
|
|
29358
|
+
isDerive: attrs.derives.length > 0,
|
|
29359
|
+
derives: [...attrs.derives]
|
|
29360
|
+
};
|
|
29361
|
+
}
|
|
29362
|
+
function extractTrait(node, _attrs) {
|
|
29363
|
+
const nameNode = node.childForFieldName("name");
|
|
29364
|
+
return {
|
|
29365
|
+
name: nameNode?.text ?? "<anon>",
|
|
29366
|
+
line: node.startPosition.row + 1,
|
|
29367
|
+
column: node.startPosition.column,
|
|
29368
|
+
isPublic: hasVisibility(node)
|
|
29369
|
+
};
|
|
29370
|
+
}
|
|
29371
|
+
function extractImpl(node, _attrs, _ctx) {
|
|
29372
|
+
const traitNode = node.childForFieldName("trait");
|
|
29373
|
+
const typeNode = node.childForFieldName("type");
|
|
29374
|
+
const typeText = typeNode?.text ?? "<anon>";
|
|
29375
|
+
const traitText = traitNode?.text;
|
|
29376
|
+
const body = node.childForFieldName("body");
|
|
29377
|
+
const methods = [];
|
|
29378
|
+
if (body) {
|
|
29379
|
+
for (let i = 0; i < body.namedChildCount; i++) {
|
|
29380
|
+
const child = body.namedChild(i);
|
|
29381
|
+
if (child?.type === "function_item") {
|
|
29382
|
+
const m = child.childForFieldName("name");
|
|
29383
|
+
if (m) methods.push(m.text);
|
|
29384
|
+
}
|
|
29385
|
+
}
|
|
29203
29386
|
}
|
|
29204
|
-
|
|
29205
|
-
|
|
29206
|
-
|
|
29207
|
-
|
|
29208
|
-
|
|
29209
|
-
|
|
29387
|
+
return {
|
|
29388
|
+
entry: {
|
|
29389
|
+
type: typeText,
|
|
29390
|
+
trait: traitText ?? void 0,
|
|
29391
|
+
methods,
|
|
29392
|
+
line: node.startPosition.row + 1,
|
|
29393
|
+
column: node.startPosition.column
|
|
29394
|
+
}
|
|
29395
|
+
};
|
|
29396
|
+
}
|
|
29397
|
+
function findUseListNode(argument) {
|
|
29398
|
+
if (!argument) return null;
|
|
29399
|
+
if (argument.type === "use_list") return argument;
|
|
29400
|
+
if (argument.type === "scoped_use_list") {
|
|
29401
|
+
for (let i = 0; i < argument.namedChildCount; i++) {
|
|
29402
|
+
const c = argument.namedChild(i);
|
|
29403
|
+
if (c?.type === "use_list") return c;
|
|
29404
|
+
}
|
|
29210
29405
|
}
|
|
29211
|
-
|
|
29212
|
-
|
|
29213
|
-
|
|
29214
|
-
|
|
29215
|
-
|
|
29216
|
-
|
|
29406
|
+
return null;
|
|
29407
|
+
}
|
|
29408
|
+
function getField(node, fieldName) {
|
|
29409
|
+
return node.childForFieldName(fieldName);
|
|
29410
|
+
}
|
|
29411
|
+
function collectIdentifiers(node) {
|
|
29412
|
+
const out = [];
|
|
29413
|
+
for (let i = 0; i < node.namedChildCount; i++) {
|
|
29414
|
+
const child = node.namedChild(i);
|
|
29415
|
+
if (!child) continue;
|
|
29416
|
+
if (child.type === "identifier" || child.type === "type_identifier") {
|
|
29417
|
+
out.push(child.text);
|
|
29418
|
+
} else if (child.type === "scoped_identifier" || child.type === "nested_identifier") {
|
|
29419
|
+
out.push(...collectIdentifiers(child));
|
|
29420
|
+
}
|
|
29217
29421
|
}
|
|
29218
|
-
|
|
29219
|
-
|
|
29220
|
-
|
|
29221
|
-
|
|
29222
|
-
|
|
29223
|
-
|
|
29422
|
+
return out;
|
|
29423
|
+
}
|
|
29424
|
+
function hasVisibility(node) {
|
|
29425
|
+
return node.namedChild(0)?.type === "visibility_modifier";
|
|
29426
|
+
}
|
|
29427
|
+
function isInImplBlock(node) {
|
|
29428
|
+
for (let p = node.parent; p; p = p.parent) {
|
|
29429
|
+
if (p.type === "impl_item") return true;
|
|
29430
|
+
if (p.type === "function_item" || p.type === "source_file") return false;
|
|
29224
29431
|
}
|
|
29225
|
-
|
|
29226
|
-
|
|
29227
|
-
|
|
29228
|
-
|
|
29229
|
-
|
|
29432
|
+
return false;
|
|
29433
|
+
}
|
|
29434
|
+
function findSelfParameter(params) {
|
|
29435
|
+
for (let i = 0; i < params.namedChildCount; i++) {
|
|
29436
|
+
const child = params.namedChild(i);
|
|
29437
|
+
if (child?.type === "self_parameter") return child;
|
|
29230
29438
|
}
|
|
29231
|
-
return
|
|
29439
|
+
return null;
|
|
29232
29440
|
}
|
|
29233
|
-
|
|
29234
|
-
|
|
29235
|
-
|
|
29441
|
+
function isFunctionAttrTest(node) {
|
|
29442
|
+
void node;
|
|
29443
|
+
return false;
|
|
29444
|
+
}
|
|
29445
|
+
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;
|
|
29446
|
+
var init_rust = __esm({
|
|
29447
|
+
"src/engine/visitors/rust.ts"() {
|
|
29236
29448
|
"use strict";
|
|
29237
|
-
|
|
29449
|
+
init_parser_rust();
|
|
29450
|
+
SERVICE_SUFFIXES4 = [
|
|
29451
|
+
"Service",
|
|
29452
|
+
"Manager",
|
|
29453
|
+
"Handler",
|
|
29454
|
+
"Repository",
|
|
29455
|
+
"Controller",
|
|
29456
|
+
"Helper",
|
|
29457
|
+
"Factory",
|
|
29458
|
+
"Provider",
|
|
29459
|
+
"Store",
|
|
29460
|
+
"API",
|
|
29461
|
+
"Client",
|
|
29462
|
+
"Adapter",
|
|
29463
|
+
"Resolver",
|
|
29464
|
+
"Mapper",
|
|
29465
|
+
"Transformer",
|
|
29466
|
+
"Serializer",
|
|
29467
|
+
"Validator",
|
|
29468
|
+
"Strategy",
|
|
29469
|
+
"Facade",
|
|
29470
|
+
"Decorator",
|
|
29471
|
+
"Observer",
|
|
29472
|
+
"Builder",
|
|
29473
|
+
"Command",
|
|
29474
|
+
"Processor",
|
|
29475
|
+
"Worker",
|
|
29476
|
+
"Job",
|
|
29477
|
+
"Actor",
|
|
29478
|
+
"Executor"
|
|
29479
|
+
];
|
|
29480
|
+
SERVICE_SUFFIX_GROUP4 = `(?:${SERVICE_SUFFIXES4.join("|")})`;
|
|
29481
|
+
RUST_SERVICE_STRUCT_RE = new RegExp(
|
|
29482
|
+
`^(?:pub(?:\\(crate\\)|\\(super\\))?\\s+)?struct\\s+(\\w+?)${SERVICE_SUFFIX_GROUP4}?\\b`,
|
|
29483
|
+
"gm"
|
|
29484
|
+
);
|
|
29485
|
+
RUST_SERVICE_IMPL_RE = new RegExp(
|
|
29486
|
+
`^impl(?:<[^>]+>)?\\s+(?:${SERVICE_SUFFIX_GROUP4}\\s+for\\s+)?(\\w+?)${SERVICE_SUFFIX_GROUP4}?\\b`,
|
|
29487
|
+
"gm"
|
|
29488
|
+
);
|
|
29489
|
+
RUST_ACTIX_ROUTE_RE = /#\[(?:get|post|put|delete|patch|head|route)\(\s*"(\/[^"]+)"\s*[\),]/g;
|
|
29490
|
+
RUST_AXUM_ROUTE_RE = /\.route\(\s*"(\/[^"]+)"\s*,\s*(?:get|post|put|delete|patch)/g;
|
|
29491
|
+
RUST_DIESEL_RE = /#\[derive\([^\]]*Queryable[^\]]*\)\][\s\S]{0,200}?struct\s+(\w+)/g;
|
|
29492
|
+
RUST_SEAORM_RE = /#\[derive\([^\]]*DeriveEntityModel[^\]]*\)\][\s\S]{0,200}?struct\s+(\w+)/g;
|
|
29493
|
+
RUST_SQLX_RE = /#\[derive\([^\]]*sqlx::FromRow[^\]]*\)\][\s\S]{0,200}?struct\s+(\w+)/g;
|
|
29494
|
+
}
|
|
29495
|
+
});
|
|
29496
|
+
|
|
29497
|
+
// src/engine/visitors/cpp.ts
|
|
29498
|
+
var cpp_exports = {};
|
|
29499
|
+
__export(cpp_exports, {
|
|
29500
|
+
extractCppPatterns: () => extractCppPatterns
|
|
29501
|
+
});
|
|
29502
|
+
function extractCppPatterns(filePath, source) {
|
|
29503
|
+
const service = [];
|
|
29504
|
+
const route = [];
|
|
29505
|
+
const ormModel = [];
|
|
29506
|
+
const seenService = /* @__PURE__ */ new Set();
|
|
29507
|
+
for (const m of source.matchAll(CPP_SERVICE_RE)) {
|
|
29508
|
+
const name = m[1];
|
|
29509
|
+
if (seenService.has(name)) continue;
|
|
29510
|
+
seenService.add(name);
|
|
29511
|
+
service.push({ name, files: [filePath], imports: [] });
|
|
29512
|
+
}
|
|
29513
|
+
const seenRoute = /* @__PURE__ */ new Set();
|
|
29514
|
+
for (const m of source.matchAll(CPP_CROW_ROUTE_RE)) {
|
|
29515
|
+
const name = m[1];
|
|
29516
|
+
if (seenRoute.has(name)) continue;
|
|
29517
|
+
seenRoute.add(name);
|
|
29518
|
+
route.push({ name, files: [filePath], imports: [] });
|
|
29519
|
+
}
|
|
29520
|
+
for (const m of source.matchAll(CPP_DROGON_ROUTE_RE)) {
|
|
29521
|
+
const name = m[1] || m[2];
|
|
29522
|
+
if (!name) continue;
|
|
29523
|
+
if (seenRoute.has(name)) continue;
|
|
29524
|
+
seenRoute.add(name);
|
|
29525
|
+
route.push({ name, files: [filePath], imports: [] });
|
|
29526
|
+
}
|
|
29527
|
+
for (const m of source.matchAll(CPP_PISTACHE_ROUTE_RE)) {
|
|
29528
|
+
const name = m[1];
|
|
29529
|
+
if (seenRoute.has(name)) continue;
|
|
29530
|
+
seenRoute.add(name);
|
|
29531
|
+
route.push({ name, files: [filePath], imports: [] });
|
|
29532
|
+
}
|
|
29533
|
+
return { service, route, ormModel };
|
|
29534
|
+
}
|
|
29535
|
+
var SERVICE_SUFFIXES5, SERVICE_SUFFIX_GROUP5, CPP_SERVICE_RE, CPP_CROW_ROUTE_RE, CPP_DROGON_ROUTE_RE, CPP_PISTACHE_ROUTE_RE;
|
|
29536
|
+
var init_cpp = __esm({
|
|
29537
|
+
"src/engine/visitors/cpp.ts"() {
|
|
29538
|
+
"use strict";
|
|
29539
|
+
SERVICE_SUFFIXES5 = [
|
|
29540
|
+
"Service",
|
|
29541
|
+
"Manager",
|
|
29542
|
+
"Handler",
|
|
29543
|
+
"Repository",
|
|
29544
|
+
"Controller",
|
|
29545
|
+
"Helper",
|
|
29546
|
+
"Factory",
|
|
29547
|
+
"Provider",
|
|
29548
|
+
"Store",
|
|
29549
|
+
"API",
|
|
29550
|
+
"Client",
|
|
29551
|
+
"Adapter",
|
|
29552
|
+
"Resolver",
|
|
29553
|
+
"Mapper",
|
|
29554
|
+
"Transformer",
|
|
29555
|
+
"Serializer",
|
|
29556
|
+
"Validator",
|
|
29557
|
+
"Strategy",
|
|
29558
|
+
"Facade",
|
|
29559
|
+
"Decorator",
|
|
29560
|
+
"Observer",
|
|
29561
|
+
"Builder",
|
|
29562
|
+
"Command",
|
|
29563
|
+
"Processor",
|
|
29564
|
+
"Worker",
|
|
29565
|
+
"Job"
|
|
29566
|
+
];
|
|
29567
|
+
SERVICE_SUFFIX_GROUP5 = `(?:${SERVICE_SUFFIXES5.join("|")})`;
|
|
29568
|
+
CPP_SERVICE_RE = new RegExp(
|
|
29569
|
+
`^(?: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`,
|
|
29570
|
+
"gm"
|
|
29571
|
+
);
|
|
29572
|
+
CPP_CROW_ROUTE_RE = /CROW_ROUTE\s*\(\s*\w+\s*,\s*"(\/[^"]+)"/g;
|
|
29573
|
+
CPP_DROGON_ROUTE_RE = /\.registerHandler\(\s*"(\/[^"]+)"[\s,)]|\.\b(?:get|post|put|delete|patch)\(\s*"(\/[^"]+)"/g;
|
|
29574
|
+
CPP_PISTACHE_ROUTE_RE = /Routes::(?:get|post|put|delete|patch)\s*\(\s*[^,]+,\s*"(\/[^"]+)"/g;
|
|
29575
|
+
}
|
|
29576
|
+
});
|
|
29577
|
+
|
|
29578
|
+
// src/engine/visitors/java.ts
|
|
29579
|
+
var java_exports = {};
|
|
29580
|
+
__export(java_exports, {
|
|
29581
|
+
extractJavaPatterns: () => extractJavaPatterns
|
|
29582
|
+
});
|
|
29583
|
+
function extractJavaPatterns(filePath, source) {
|
|
29584
|
+
const service = [];
|
|
29585
|
+
const route = [];
|
|
29586
|
+
const ormModel = [];
|
|
29587
|
+
const seenService = /* @__PURE__ */ new Set();
|
|
29588
|
+
for (const m of source.matchAll(JAVA_SERVICE_RE)) {
|
|
29589
|
+
const name = m[1];
|
|
29590
|
+
if (seenService.has(name)) continue;
|
|
29591
|
+
seenService.add(name);
|
|
29592
|
+
service.push({ name, files: [filePath], imports: [] });
|
|
29593
|
+
}
|
|
29594
|
+
const seenRoute = /* @__PURE__ */ new Set();
|
|
29595
|
+
for (const m of source.matchAll(JAVA_SPRING_ROUTE_RE)) {
|
|
29596
|
+
const name = m[1];
|
|
29597
|
+
if (seenRoute.has(name)) continue;
|
|
29598
|
+
seenRoute.add(name);
|
|
29599
|
+
route.push({ name, files: [filePath], imports: [] });
|
|
29600
|
+
}
|
|
29601
|
+
for (const m of source.matchAll(JAVA_JAXRS_CLASS_PATH_RE)) {
|
|
29602
|
+
const name = m[1];
|
|
29603
|
+
if (name === "" || name === "/") continue;
|
|
29604
|
+
if (seenRoute.has(name)) continue;
|
|
29605
|
+
seenRoute.add(name);
|
|
29606
|
+
route.push({ name, files: [filePath], imports: [] });
|
|
29607
|
+
}
|
|
29608
|
+
const seenOrm = /* @__PURE__ */ new Set();
|
|
29609
|
+
for (const m of source.matchAll(JAVA_ORM_ANNOTATION_RE)) {
|
|
29610
|
+
const name = m[1];
|
|
29611
|
+
if (seenOrm.has(name)) continue;
|
|
29612
|
+
seenOrm.add(name);
|
|
29613
|
+
ormModel.push({ name, files: [filePath], imports: [] });
|
|
29614
|
+
}
|
|
29615
|
+
for (const m of source.matchAll(JAVA_ORM_INHERIT_RE)) {
|
|
29616
|
+
const name = m[1];
|
|
29617
|
+
if (seenOrm.has(name)) continue;
|
|
29618
|
+
seenOrm.add(name);
|
|
29619
|
+
ormModel.push({ name, files: [filePath], imports: [] });
|
|
29620
|
+
}
|
|
29621
|
+
return { service, route, ormModel };
|
|
29622
|
+
}
|
|
29623
|
+
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;
|
|
29624
|
+
var init_java = __esm({
|
|
29625
|
+
"src/engine/visitors/java.ts"() {
|
|
29626
|
+
"use strict";
|
|
29627
|
+
SERVICE_SUFFIXES6 = [
|
|
29238
29628
|
"Service",
|
|
29239
29629
|
"Manager",
|
|
29240
29630
|
"Handler",
|
|
@@ -30945,6 +31335,246 @@ var init_broken_link = __esm({
|
|
|
30945
31335
|
}
|
|
30946
31336
|
});
|
|
30947
31337
|
|
|
31338
|
+
// src/rules/dup/identical-block.ts
|
|
31339
|
+
import * as crypto from "crypto";
|
|
31340
|
+
function normalizeAndHash(lines) {
|
|
31341
|
+
const normalized = lines.map(
|
|
31342
|
+
(line) => line.replace(/\/\/.*$/, "").replace(/\/\*[\s\S]*?\*\//g, "").replace(/\s+/g, " ").trim()
|
|
31343
|
+
).filter((line) => line.length > 0).join("\n");
|
|
31344
|
+
if (normalized.length < MIN_NORMALIZED_LENGTH) return void 0;
|
|
31345
|
+
return crypto.createHash("sha1").update(normalized).digest("hex").slice(0, HASH_PREFIX_LENGTH);
|
|
31346
|
+
}
|
|
31347
|
+
var WINDOW_SIZE, MIN_NORMALIZED_LENGTH, HASH_PREFIX_LENGTH, DEDUP_CACHE, dupIdenticalBlockRule;
|
|
31348
|
+
var init_identical_block = __esm({
|
|
31349
|
+
"src/rules/dup/identical-block.ts"() {
|
|
31350
|
+
"use strict";
|
|
31351
|
+
init_rule();
|
|
31352
|
+
WINDOW_SIZE = 10;
|
|
31353
|
+
MIN_NORMALIZED_LENGTH = 40;
|
|
31354
|
+
HASH_PREFIX_LENGTH = 16;
|
|
31355
|
+
DEDUP_CACHE = /* @__PURE__ */ new Map();
|
|
31356
|
+
dupIdenticalBlockRule = createRule({
|
|
31357
|
+
id: "dup/identical-block",
|
|
31358
|
+
category: "logic",
|
|
31359
|
+
severity: "medium",
|
|
31360
|
+
aiSpecific: false,
|
|
31361
|
+
description: "Block of >=10 lines is identical across >=2 files (Type-1 clone detector)",
|
|
31362
|
+
create(_context) {
|
|
31363
|
+
return {};
|
|
31364
|
+
},
|
|
31365
|
+
analyze(_context, facts) {
|
|
31366
|
+
const issues = [];
|
|
31367
|
+
const source = facts.v2?._source;
|
|
31368
|
+
if (!source) return issues;
|
|
31369
|
+
const filePath = facts.filePath;
|
|
31370
|
+
const lines = source.split("\n");
|
|
31371
|
+
for (let i = 0; i <= lines.length - WINDOW_SIZE; i++) {
|
|
31372
|
+
const window = lines.slice(i, i + WINDOW_SIZE);
|
|
31373
|
+
const hash = normalizeAndHash(window);
|
|
31374
|
+
if (!hash) continue;
|
|
31375
|
+
const existing = DEDUP_CACHE.get(hash) ?? [];
|
|
31376
|
+
const matches = existing.filter((m) => m.file !== filePath);
|
|
31377
|
+
for (const match of matches) {
|
|
31378
|
+
issues.push({
|
|
31379
|
+
ruleId: "dup/identical-block",
|
|
31380
|
+
category: "logic",
|
|
31381
|
+
severity: "medium",
|
|
31382
|
+
aiSpecific: false,
|
|
31383
|
+
message: `Identical ${WINDOW_SIZE}-line block at line ${i + 1} also appears in ${match.file}:${match.line + 1}`,
|
|
31384
|
+
line: i + 1,
|
|
31385
|
+
column: 0,
|
|
31386
|
+
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.",
|
|
31387
|
+
extras: {
|
|
31388
|
+
duplicateOf: {
|
|
31389
|
+
file: match.file,
|
|
31390
|
+
line: match.line + 1,
|
|
31391
|
+
hash
|
|
31392
|
+
}
|
|
31393
|
+
}
|
|
31394
|
+
});
|
|
31395
|
+
}
|
|
31396
|
+
existing.push({ file: filePath, line: i });
|
|
31397
|
+
DEDUP_CACHE.set(hash, existing);
|
|
31398
|
+
}
|
|
31399
|
+
return issues;
|
|
31400
|
+
}
|
|
31401
|
+
});
|
|
31402
|
+
}
|
|
31403
|
+
});
|
|
31404
|
+
|
|
31405
|
+
// src/rules/go/error-wrap-without-context.ts
|
|
31406
|
+
var ERR_WRAP_REGEX, GENERIC_PREFIX_REGEX, goErrorWrapWithoutContextRule;
|
|
31407
|
+
var init_error_wrap_without_context = __esm({
|
|
31408
|
+
"src/rules/go/error-wrap-without-context.ts"() {
|
|
31409
|
+
"use strict";
|
|
31410
|
+
init_rule();
|
|
31411
|
+
ERR_WRAP_REGEX = /fmt\.Errorf\(\s*"((?:[^"\\]|\\.)*)"\s*,\s*([^)]+)\)/g;
|
|
31412
|
+
GENERIC_PREFIX_REGEX = /^\s*(?:error|err|failed|wrap(?:ping)?|invalid)\s*(?::\s*)?%w\b/i;
|
|
31413
|
+
goErrorWrapWithoutContextRule = createRule({
|
|
31414
|
+
id: "go/error-wrap-without-context",
|
|
31415
|
+
category: "typo",
|
|
31416
|
+
severity: "low",
|
|
31417
|
+
aiSpecific: true,
|
|
31418
|
+
description: 'fmt.Errorf wrap without operation context \u2014 AI defaults to generic "error: %w"',
|
|
31419
|
+
create(_context) {
|
|
31420
|
+
return {};
|
|
31421
|
+
},
|
|
31422
|
+
analyze(_context, facts) {
|
|
31423
|
+
const issues = [];
|
|
31424
|
+
const source = facts.v2?._source;
|
|
31425
|
+
if (!source) return issues;
|
|
31426
|
+
let match;
|
|
31427
|
+
ERR_WRAP_REGEX.lastIndex = 0;
|
|
31428
|
+
while ((match = ERR_WRAP_REGEX.exec(source)) !== null) {
|
|
31429
|
+
const formatString = match[1];
|
|
31430
|
+
if (!formatString.includes("%w")) continue;
|
|
31431
|
+
if (formatString.length >= 30) continue;
|
|
31432
|
+
if (!GENERIC_PREFIX_REGEX.test(formatString)) continue;
|
|
31433
|
+
const line = source.slice(0, match.index).split("\n").length;
|
|
31434
|
+
issues.push({
|
|
31435
|
+
ruleId: "go/error-wrap-without-context",
|
|
31436
|
+
category: "typo",
|
|
31437
|
+
severity: "low",
|
|
31438
|
+
aiSpecific: true,
|
|
31439
|
+
message: `fmt.Errorf wrap with generic message "${formatString}" \u2014 include the failing operation`,
|
|
31440
|
+
line,
|
|
31441
|
+
column: match[0].indexOf("fmt") + 1,
|
|
31442
|
+
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'
|
|
31443
|
+
});
|
|
31444
|
+
}
|
|
31445
|
+
return issues;
|
|
31446
|
+
}
|
|
31447
|
+
});
|
|
31448
|
+
}
|
|
31449
|
+
});
|
|
31450
|
+
|
|
31451
|
+
// src/rules/go/nil-slice-vs-empty.ts
|
|
31452
|
+
var NIL_SLICE_DECL_REGEX, EMPTY_SLICE_ASSIGN_REGEX, goNilSliceVsEmptyRule;
|
|
31453
|
+
var init_nil_slice_vs_empty = __esm({
|
|
31454
|
+
"src/rules/go/nil-slice-vs-empty.ts"() {
|
|
31455
|
+
"use strict";
|
|
31456
|
+
init_rule();
|
|
31457
|
+
NIL_SLICE_DECL_REGEX = /^[\t ]*var\s+([A-Za-z_][A-Za-z0-9_]*)\s+\[\][\w.*]+\b/gm;
|
|
31458
|
+
EMPTY_SLICE_ASSIGN_REGEX = /^[\t ]*([A-Za-z_][A-Za-z0-9_]*)\s*=\s*(?:\[\][\w.*]*\{\}|make\(\[\][\w.*]*)/gm;
|
|
31459
|
+
goNilSliceVsEmptyRule = createRule({
|
|
31460
|
+
id: "go/nil-slice-vs-empty",
|
|
31461
|
+
category: "typo",
|
|
31462
|
+
severity: "low",
|
|
31463
|
+
aiSpecific: true,
|
|
31464
|
+
description: "Variable declared `var x []int` but later assigned `x = []int{}` or `make([]int, n)` \u2014 pick one form",
|
|
31465
|
+
create(_context) {
|
|
31466
|
+
return {};
|
|
31467
|
+
},
|
|
31468
|
+
analyze(_context, facts) {
|
|
31469
|
+
const issues = [];
|
|
31470
|
+
const source = facts.v2?._source;
|
|
31471
|
+
if (!source) return issues;
|
|
31472
|
+
const nilDecls = /* @__PURE__ */ new Map();
|
|
31473
|
+
let m;
|
|
31474
|
+
NIL_SLICE_DECL_REGEX.lastIndex = 0;
|
|
31475
|
+
while ((m = NIL_SLICE_DECL_REGEX.exec(source)) !== null) {
|
|
31476
|
+
nilDecls.set(m[1], source.slice(0, m.index).split("\n").length);
|
|
31477
|
+
}
|
|
31478
|
+
if (nilDecls.size === 0) return issues;
|
|
31479
|
+
EMPTY_SLICE_ASSIGN_REGEX.lastIndex = 0;
|
|
31480
|
+
while ((m = EMPTY_SLICE_ASSIGN_REGEX.exec(source)) !== null) {
|
|
31481
|
+
const name = m[1];
|
|
31482
|
+
if (!nilDecls.has(name)) continue;
|
|
31483
|
+
const declLine = nilDecls.get(name);
|
|
31484
|
+
const assignLine = source.slice(0, m.index).split("\n").length;
|
|
31485
|
+
if (assignLine <= declLine) continue;
|
|
31486
|
+
issues.push({
|
|
31487
|
+
ruleId: "go/nil-slice-vs-empty",
|
|
31488
|
+
category: "typo",
|
|
31489
|
+
severity: "low",
|
|
31490
|
+
aiSpecific: true,
|
|
31491
|
+
message: `Variable '${name}' declared as nil slice (line ${declLine}) but assigned an empty slice (line ${assignLine}) \u2014 pick one form`,
|
|
31492
|
+
line: declLine,
|
|
31493
|
+
column: 1,
|
|
31494
|
+
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."
|
|
31495
|
+
});
|
|
31496
|
+
}
|
|
31497
|
+
return issues;
|
|
31498
|
+
}
|
|
31499
|
+
});
|
|
31500
|
+
}
|
|
31501
|
+
});
|
|
31502
|
+
|
|
31503
|
+
// src/rules/go/struct-tag-inconsistency.ts
|
|
31504
|
+
var JSON_TAG_REGEX, goStructTagInconsistencyRule;
|
|
31505
|
+
var init_struct_tag_inconsistency = __esm({
|
|
31506
|
+
"src/rules/go/struct-tag-inconsistency.ts"() {
|
|
31507
|
+
"use strict";
|
|
31508
|
+
init_rule();
|
|
31509
|
+
JSON_TAG_REGEX = /`json:"([^",]+)(?:,([^"]+))?"`/g;
|
|
31510
|
+
goStructTagInconsistencyRule = createRule({
|
|
31511
|
+
id: "go/struct-tag-inconsistency",
|
|
31512
|
+
category: "typo",
|
|
31513
|
+
severity: "low",
|
|
31514
|
+
aiSpecific: true,
|
|
31515
|
+
description: 'Struct fields mix json:"foo" and json:"foo,omitempty" \u2014 pick one convention per struct',
|
|
31516
|
+
create(_context) {
|
|
31517
|
+
return {};
|
|
31518
|
+
},
|
|
31519
|
+
analyze(_context, facts) {
|
|
31520
|
+
const issues = [];
|
|
31521
|
+
const source = facts.v2?._source;
|
|
31522
|
+
if (!source) return issues;
|
|
31523
|
+
const structRegex = /type\s+[A-Z][A-Za-z0-9_]*\s+struct\s*\{/g;
|
|
31524
|
+
let structMatch;
|
|
31525
|
+
while ((structMatch = structRegex.exec(source)) !== null) {
|
|
31526
|
+
const startIdx = structMatch.index;
|
|
31527
|
+
const openBrace = source.indexOf("{", startIdx);
|
|
31528
|
+
if (openBrace < 0) continue;
|
|
31529
|
+
let depth = 1;
|
|
31530
|
+
let i = openBrace + 1;
|
|
31531
|
+
while (i < source.length && depth > 0) {
|
|
31532
|
+
const ch = source[i];
|
|
31533
|
+
if (ch === "{") depth++;
|
|
31534
|
+
else if (ch === "}") depth--;
|
|
31535
|
+
i++;
|
|
31536
|
+
}
|
|
31537
|
+
const structBody = source.slice(openBrace, i);
|
|
31538
|
+
const structLine = source.slice(0, startIdx).split("\n").length;
|
|
31539
|
+
const styleCount = {};
|
|
31540
|
+
const tagMatches = [];
|
|
31541
|
+
let m;
|
|
31542
|
+
JSON_TAG_REGEX.lastIndex = 0;
|
|
31543
|
+
while ((m = JSON_TAG_REGEX.exec(structBody)) !== null) {
|
|
31544
|
+
const tag = m[1];
|
|
31545
|
+
const options = m[2] ?? "";
|
|
31546
|
+
const style = options ? "with-options" : "no-options";
|
|
31547
|
+
styleCount[style] = (styleCount[style] ?? 0) + 1;
|
|
31548
|
+
tagMatches.push({ tag, style, idx: openBrace + m.index });
|
|
31549
|
+
}
|
|
31550
|
+
const styles = Object.keys(styleCount);
|
|
31551
|
+
if (styles.length < 2 || tagMatches.length < 2) continue;
|
|
31552
|
+
const dominant = styles.reduce(
|
|
31553
|
+
(a, b) => (styleCount[a] ?? 0) >= (styleCount[b] ?? 0) ? a : b
|
|
31554
|
+
);
|
|
31555
|
+
const minority = tagMatches.filter((t) => t.style !== dominant);
|
|
31556
|
+
if (minority.length === 0) continue;
|
|
31557
|
+
for (const m2 of minority) {
|
|
31558
|
+
const line = source.slice(0, m2.idx).split("\n").length;
|
|
31559
|
+
issues.push({
|
|
31560
|
+
ruleId: "go/struct-tag-inconsistency",
|
|
31561
|
+
category: "typo",
|
|
31562
|
+
severity: "low",
|
|
31563
|
+
aiSpecific: true,
|
|
31564
|
+
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"}`,
|
|
31565
|
+
line,
|
|
31566
|
+
column: 1,
|
|
31567
|
+
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.'
|
|
31568
|
+
});
|
|
31569
|
+
}
|
|
31570
|
+
if (issues.length > 0) break;
|
|
31571
|
+
}
|
|
31572
|
+
return issues;
|
|
31573
|
+
}
|
|
31574
|
+
});
|
|
31575
|
+
}
|
|
31576
|
+
});
|
|
31577
|
+
|
|
30948
31578
|
// src/rules/layout/gap-monopoly.ts
|
|
30949
31579
|
var GAP_RE, gapMonopolyRule;
|
|
30950
31580
|
var init_gap_monopoly = __esm({
|
|
@@ -35835,11 +36465,11 @@ __export(dist_exports2, {
|
|
|
35835
36465
|
tokenizeIdentifiers: () => tokenizeIdentifiers
|
|
35836
36466
|
});
|
|
35837
36467
|
import { readFile, writeFile, mkdir, access } from "fs/promises";
|
|
35838
|
-
import { createHash } from "crypto";
|
|
36468
|
+
import { createHash as createHash2 } from "crypto";
|
|
35839
36469
|
import { join as join10, dirname as dirname6 } from "path";
|
|
35840
36470
|
import { parseSync } from "@swc/core";
|
|
35841
36471
|
import { join as join22 } from "path";
|
|
35842
|
-
import { createHash as
|
|
36472
|
+
import { createHash as createHash22 } from "crypto";
|
|
35843
36473
|
import { createHash as createHash3 } from "crypto";
|
|
35844
36474
|
import { readFile as readFile2 } from "fs/promises";
|
|
35845
36475
|
import { relative as relative3 } from "path";
|
|
@@ -36051,7 +36681,7 @@ function parseBlankModule(source) {
|
|
|
36051
36681
|
tsx: false,
|
|
36052
36682
|
target: "es2022"
|
|
36053
36683
|
});
|
|
36054
|
-
return { ast, source
|
|
36684
|
+
return { ast, source };
|
|
36055
36685
|
}
|
|
36056
36686
|
function parseScriptContent(content, isTypeScript) {
|
|
36057
36687
|
if (isTypeScript) {
|
|
@@ -36093,7 +36723,7 @@ function legacyCacheRoot() {
|
|
|
36093
36723
|
return join10(process.cwd(), ".slopbrick", "cache", "ast");
|
|
36094
36724
|
}
|
|
36095
36725
|
function hashContent(content) {
|
|
36096
|
-
return
|
|
36726
|
+
return createHash2("md5").update(content, "utf-8").digest("hex");
|
|
36097
36727
|
}
|
|
36098
36728
|
function cachePathWithRoot(content, root) {
|
|
36099
36729
|
return join10(root, `${hashContent(content)}.json`);
|
|
@@ -36137,8 +36767,16 @@ function parseSource(source, filePath) {
|
|
|
36137
36767
|
// but no SWC support. Return a blank-padded empty module so
|
|
36138
36768
|
// regex-only rules can still fire (markdown-leakage, comment-
|
|
36139
36769
|
// ratio, etc.) without burning the parseError path.
|
|
36770
|
+
// v0.18.9: `.rs` is in the same bucket. The visitor layer
|
|
36771
|
+
// (`engine/visitors/rust.ts`) carries the tree-sitter-backed
|
|
36772
|
+
// parse + extractFacts attaches the result to `facts.v2.rustFile`.
|
|
36773
|
+
// The rule layer (`rules/rust/*.ts`) reads that field. parseBlankModule
|
|
36774
|
+
// lets the worker continue past the parser — without this, parseWithSwc
|
|
36775
|
+
// would throw on every .rs file, the worker would count it as a
|
|
36776
|
+
// parseError, and the v2-build's buildRustFileRecord would never run.
|
|
36140
36777
|
case "py":
|
|
36141
36778
|
case "go":
|
|
36779
|
+
case "rs":
|
|
36142
36780
|
return parseBlankModule(source);
|
|
36143
36781
|
default:
|
|
36144
36782
|
return parseWithSwc(source, filePath);
|
|
@@ -36283,7 +36921,7 @@ function fingerprintFor(component) {
|
|
|
36283
36921
|
const hooks = component.hookCalls.map((h) => h.name).sort();
|
|
36284
36922
|
const props = component.props.map((p) => p.name).sort();
|
|
36285
36923
|
const payload = `${component.name}|${hooks.join(",")}|${props.join(",")}`;
|
|
36286
|
-
return
|
|
36924
|
+
return createHash22("sha256").update(payload).digest("hex").slice(0, 16);
|
|
36287
36925
|
}
|
|
36288
36926
|
function buildComponentFingerprints(results) {
|
|
36289
36927
|
const byName = /* @__PURE__ */ new Map();
|
|
@@ -38225,91 +38863,6 @@ var init_key_prop_missing = __esm({
|
|
|
38225
38863
|
}
|
|
38226
38864
|
});
|
|
38227
38865
|
|
|
38228
|
-
// src/rules/logic/ks-distribution-shift.ts
|
|
38229
|
-
function extractFileFeatures(source) {
|
|
38230
|
-
const lines = source.split("\n");
|
|
38231
|
-
const lineLengths = lines.map((l) => l.length);
|
|
38232
|
-
const identifierLengths = [];
|
|
38233
|
-
const idRe = /[A-Za-z_$][A-Za-z0-9_$]*/g;
|
|
38234
|
-
let m;
|
|
38235
|
-
while ((m = idRe.exec(source)) !== null) {
|
|
38236
|
-
identifierLengths.push(m[0].length);
|
|
38237
|
-
}
|
|
38238
|
-
const commentDensity = lines.map((l) => {
|
|
38239
|
-
const trimmed = l.trim();
|
|
38240
|
-
if (trimmed.length === 0) return 0;
|
|
38241
|
-
const commentChars = (trimmed.match(/^\/\/.*$/)?.[0]?.length ?? 0) + (trimmed.match(/^\s*\/\*.*?\*\/\s*$/)?.at(0)?.length ?? 0);
|
|
38242
|
-
return commentChars / trimmed.length;
|
|
38243
|
-
});
|
|
38244
|
-
return { lineLengths, identifierLengths, commentDensity };
|
|
38245
|
-
}
|
|
38246
|
-
var MIN_SAMPLES_PER_FEATURE, ksDistributionShiftRule;
|
|
38247
|
-
var init_ks_distribution_shift = __esm({
|
|
38248
|
-
"src/rules/logic/ks-distribution-shift.ts"() {
|
|
38249
|
-
"use strict";
|
|
38250
|
-
init_rule();
|
|
38251
|
-
init_dist2();
|
|
38252
|
-
init_corpus_baselines2();
|
|
38253
|
-
MIN_SAMPLES_PER_FEATURE = 20;
|
|
38254
|
-
ksDistributionShiftRule = createRule({
|
|
38255
|
-
id: "logic/ks-distribution-shift",
|
|
38256
|
-
category: "logic",
|
|
38257
|
-
severity: "medium",
|
|
38258
|
-
aiSpecific: false,
|
|
38259
|
-
description: "Multi-feature Kolmogorov\u2013Smirnov distribution-shift vs corpus baseline (Bonferroni-corrected). Peer-reviewed ML distribution-shift detector (arXiv:2510.15996, Oct 2025).",
|
|
38260
|
-
create(context) {
|
|
38261
|
-
return context;
|
|
38262
|
-
},
|
|
38263
|
-
analyze(_context, facts) {
|
|
38264
|
-
const issues = [];
|
|
38265
|
-
if (!facts.v2) return issues;
|
|
38266
|
-
const source = facts.v2._source ?? "";
|
|
38267
|
-
if (source.length < 200) return issues;
|
|
38268
|
-
const features = extractFileFeatures(source);
|
|
38269
|
-
const samples = /* @__PURE__ */ new Map([
|
|
38270
|
-
["lineLengths", features.lineLengths],
|
|
38271
|
-
["identifierLengths", features.identifierLengths],
|
|
38272
|
-
["commentDensity", features.commentDensity]
|
|
38273
|
-
]);
|
|
38274
|
-
const baselines = getCorpusBaselines();
|
|
38275
|
-
const baselinesMap = /* @__PURE__ */ new Map();
|
|
38276
|
-
if (baselines) {
|
|
38277
|
-
baselinesMap.set("lineLengths", baselines.features.lineLengths.sample);
|
|
38278
|
-
baselinesMap.set("identifierLengths", baselines.features.identifierLengths.sample);
|
|
38279
|
-
baselinesMap.set("commentDensity", baselines.features.commentDensity.sample);
|
|
38280
|
-
} else {
|
|
38281
|
-
baselinesMap.set("lineLengths", [20, 25, 30, 32, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95, 100]);
|
|
38282
|
-
baselinesMap.set("identifierLengths", [3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 18, 20, 24, 28]);
|
|
38283
|
-
baselinesMap.set("commentDensity", [0, 0, 0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.4, 0.5]);
|
|
38284
|
-
}
|
|
38285
|
-
for (const [name, vals] of samples) {
|
|
38286
|
-
if (vals.length < MIN_SAMPLES_PER_FEATURE) samples.delete(name);
|
|
38287
|
-
}
|
|
38288
|
-
if (samples.size === 0) return issues;
|
|
38289
|
-
const result = multiFeatureKsTest(samples, baselinesMap, 0.05);
|
|
38290
|
-
if (!result.anySignificant) return issues;
|
|
38291
|
-
const shifted = result.significantFeatures.join(", ");
|
|
38292
|
-
const details = result.significantFeatures.map((name) => {
|
|
38293
|
-
const r = result.perFeature.get(name);
|
|
38294
|
-
if (!r) return name;
|
|
38295
|
-
return `${name} (D=${r.statistic.toFixed(3)}, p=${r.pValue.toExponential(2)})`;
|
|
38296
|
-
}).join("; ");
|
|
38297
|
-
issues.push({
|
|
38298
|
-
ruleId: "logic/ks-distribution-shift",
|
|
38299
|
-
category: "logic",
|
|
38300
|
-
severity: "medium",
|
|
38301
|
-
aiSpecific: true,
|
|
38302
|
-
message: `Distribution shift detected on ${result.significantFeatures.length} of ${result.perFeature.size} features (Bonferroni \u03B1=${result.bonferroniAlpha.toExponential(2)}). Features: ${shifted}. Detail: ${details}.`,
|
|
38303
|
-
line: 1,
|
|
38304
|
-
column: 1,
|
|
38305
|
-
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."
|
|
38306
|
-
});
|
|
38307
|
-
return issues;
|
|
38308
|
-
}
|
|
38309
|
-
});
|
|
38310
|
-
}
|
|
38311
|
-
});
|
|
38312
|
-
|
|
38313
38866
|
// src/rules/logic/math-any-density.ts
|
|
38314
38867
|
var ANY_PER_100_LINES, MIN_ABSOLUTE, COLON, ANY_KEYWORD, ANY_TYPE_RE, MSG_FRAGMENT, RULE_DESCRIPTION, RULE_MESSAGE, RULE_ADVICE, mathAnyDensityRule;
|
|
38315
38868
|
var init_math_any_density = __esm({
|
|
@@ -38379,13 +38932,13 @@ var init_math_any_density = __esm({
|
|
|
38379
38932
|
});
|
|
38380
38933
|
|
|
38381
38934
|
// src/rules/logic/math-console-log-storm.ts
|
|
38382
|
-
var
|
|
38935
|
+
var WINDOW_SIZE2, STORM_THRESHOLD, CONSOLE_LOG_RE, mathConsoleLogStormRule;
|
|
38383
38936
|
var init_math_console_log_storm = __esm({
|
|
38384
38937
|
"src/rules/logic/math-console-log-storm.ts"() {
|
|
38385
38938
|
"use strict";
|
|
38386
38939
|
init_rule();
|
|
38387
38940
|
init_utils();
|
|
38388
|
-
|
|
38941
|
+
WINDOW_SIZE2 = 30;
|
|
38389
38942
|
STORM_THRESHOLD = 5;
|
|
38390
38943
|
CONSOLE_LOG_RE = /\bconsole\.log\s*\(/g;
|
|
38391
38944
|
mathConsoleLogStormRule = createRule({
|
|
@@ -38416,7 +38969,7 @@ var init_math_console_log_storm = __esm({
|
|
|
38416
38969
|
let maxEndLine = 0;
|
|
38417
38970
|
let i = 0;
|
|
38418
38971
|
for (let j = 0; j < lines.length; j++) {
|
|
38419
|
-
while (lines[j] - lines[i] >
|
|
38972
|
+
while (lines[j] - lines[i] > WINDOW_SIZE2) i++;
|
|
38420
38973
|
const count = j - i + 1;
|
|
38421
38974
|
if (count > maxCount) {
|
|
38422
38975
|
maxCount = count;
|
|
@@ -38430,7 +38983,7 @@ var init_math_console_log_storm = __esm({
|
|
|
38430
38983
|
category: "logic",
|
|
38431
38984
|
severity: "high",
|
|
38432
38985
|
aiSpecific: true,
|
|
38433
|
-
message: `${maxCount} console.log calls clustered in a ${
|
|
38986
|
+
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.`,
|
|
38434
38987
|
line: firstIdx >= 0 ? lines[firstIdx] : 1,
|
|
38435
38988
|
column: firstIdx >= 0 ? columns[firstIdx] : 1,
|
|
38436
38989
|
advice: "Replace debug logs with a proper debugger or logger.debug() \u2014 remove all console.log before shipping."
|
|
@@ -39316,6 +39869,354 @@ var init_ux_pattern_fragmentation = __esm({
|
|
|
39316
39869
|
}
|
|
39317
39870
|
});
|
|
39318
39871
|
|
|
39872
|
+
// src/rules/rust/stringly-typed.ts
|
|
39873
|
+
function collectEnumCandidates(source) {
|
|
39874
|
+
const out = [];
|
|
39875
|
+
const enumRe = /^(?:pub(?:\([^)]+\))?\s+)?enum\s+(\w+)\s*\{([^}]*)\}/gm;
|
|
39876
|
+
for (const m of source.matchAll(enumRe)) {
|
|
39877
|
+
const body = m[2] ?? "";
|
|
39878
|
+
const variants = body.split(/,(?![^()]*\))/).map((s) => s.trim()).filter((s) => /^[A-Za-z_][A-Za-z0-9_]*$/.test(s.split(/\s+/)[0] ?? ""));
|
|
39879
|
+
if (variants.length > MAX_VARIANT_COUNT) continue;
|
|
39880
|
+
if (variants.length < 2) continue;
|
|
39881
|
+
out.push({ name: m[1], variantCount: variants.length, line: lineOfMatch(source, m.index ?? 0) });
|
|
39882
|
+
}
|
|
39883
|
+
return out;
|
|
39884
|
+
}
|
|
39885
|
+
function lineOfMatch(source, index) {
|
|
39886
|
+
let line = 1;
|
|
39887
|
+
for (let i = 0; i < index && i < source.length; i++) {
|
|
39888
|
+
if (source[i] === "\n") line++;
|
|
39889
|
+
}
|
|
39890
|
+
return line;
|
|
39891
|
+
}
|
|
39892
|
+
function buildLineOffsets(source) {
|
|
39893
|
+
const out = [0];
|
|
39894
|
+
for (let i = 0; i < source.length; i++) {
|
|
39895
|
+
if (source[i] === "\n") out.push(i + 1);
|
|
39896
|
+
}
|
|
39897
|
+
return out;
|
|
39898
|
+
}
|
|
39899
|
+
function extractParameterText(source, lineOffsets, fn) {
|
|
39900
|
+
const start = lineOffsets[Math.max(0, fn.line - 1)] ?? 0;
|
|
39901
|
+
const head = source.slice(start, start + 400);
|
|
39902
|
+
const openIdx = head.indexOf("(");
|
|
39903
|
+
if (openIdx < 0) return "";
|
|
39904
|
+
let closeIdx = -1;
|
|
39905
|
+
let depth = 0;
|
|
39906
|
+
for (let i = openIdx; i < head.length; i++) {
|
|
39907
|
+
if (head[i] === "(") depth++;
|
|
39908
|
+
else if (head[i] === ")") {
|
|
39909
|
+
depth--;
|
|
39910
|
+
if (depth === 0) {
|
|
39911
|
+
closeIdx = i;
|
|
39912
|
+
break;
|
|
39913
|
+
}
|
|
39914
|
+
}
|
|
39915
|
+
}
|
|
39916
|
+
if (closeIdx < 0) return "";
|
|
39917
|
+
return head.slice(openIdx + 1, closeIdx);
|
|
39918
|
+
}
|
|
39919
|
+
function scanForStringlyParams(paramText) {
|
|
39920
|
+
const out = [];
|
|
39921
|
+
for (const m of paramText.matchAll(
|
|
39922
|
+
/\b([a-z_][a-zA-Z0-9_]*)\s*:\s*(&\s*(?:mut\s+)?(?:str|String)\b)/g
|
|
39923
|
+
)) {
|
|
39924
|
+
const name = m[1];
|
|
39925
|
+
const type = m[2];
|
|
39926
|
+
if (!SUSPECT_PARAM_NAMES.has(name)) continue;
|
|
39927
|
+
out.push({ name, type });
|
|
39928
|
+
}
|
|
39929
|
+
return out;
|
|
39930
|
+
}
|
|
39931
|
+
var SUSPECT_PARAM_NAMES, MAX_VARIANT_COUNT, rustStringlyTypedRule;
|
|
39932
|
+
var init_stringly_typed = __esm({
|
|
39933
|
+
"src/rules/rust/stringly-typed.ts"() {
|
|
39934
|
+
"use strict";
|
|
39935
|
+
init_rule();
|
|
39936
|
+
SUSPECT_PARAM_NAMES = /* @__PURE__ */ new Set([
|
|
39937
|
+
"kind",
|
|
39938
|
+
"type",
|
|
39939
|
+
"mode",
|
|
39940
|
+
"event",
|
|
39941
|
+
"status",
|
|
39942
|
+
"category",
|
|
39943
|
+
"action",
|
|
39944
|
+
"state",
|
|
39945
|
+
"level",
|
|
39946
|
+
"role",
|
|
39947
|
+
"tier",
|
|
39948
|
+
"phase",
|
|
39949
|
+
"tag",
|
|
39950
|
+
"format",
|
|
39951
|
+
"shape",
|
|
39952
|
+
"direction",
|
|
39953
|
+
"side",
|
|
39954
|
+
"method"
|
|
39955
|
+
]);
|
|
39956
|
+
MAX_VARIANT_COUNT = 32;
|
|
39957
|
+
rustStringlyTypedRule = createRule({
|
|
39958
|
+
id: "rust/stringly-typed",
|
|
39959
|
+
category: "logic",
|
|
39960
|
+
severity: "medium",
|
|
39961
|
+
aiSpecific: true,
|
|
39962
|
+
description: "String / &str parameter where a typed enum exists in the same file",
|
|
39963
|
+
create(_context) {
|
|
39964
|
+
return {};
|
|
39965
|
+
},
|
|
39966
|
+
analyze(_context, facts) {
|
|
39967
|
+
const issues = [];
|
|
39968
|
+
if (!facts.v2?.rustFile) return issues;
|
|
39969
|
+
const source = facts.v2._source ?? "";
|
|
39970
|
+
if (!source) return issues;
|
|
39971
|
+
const lineOffsets = buildLineOffsets(source);
|
|
39972
|
+
const enumCandidates = collectEnumCandidates(source);
|
|
39973
|
+
if (enumCandidates.length === 0) return issues;
|
|
39974
|
+
for (const fn of facts.v2.rustFile.functions) {
|
|
39975
|
+
const paramText = extractParameterText(source, lineOffsets, fn);
|
|
39976
|
+
if (!paramText) continue;
|
|
39977
|
+
const matches = scanForStringlyParams(paramText);
|
|
39978
|
+
if (matches.length === 0) continue;
|
|
39979
|
+
issues.push({
|
|
39980
|
+
ruleId: "rust/stringly-typed",
|
|
39981
|
+
category: "logic",
|
|
39982
|
+
severity: "medium",
|
|
39983
|
+
aiSpecific: true,
|
|
39984
|
+
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`,
|
|
39985
|
+
line: fn.line,
|
|
39986
|
+
column: fn.column,
|
|
39987
|
+
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.`
|
|
39988
|
+
});
|
|
39989
|
+
}
|
|
39990
|
+
return issues;
|
|
39991
|
+
}
|
|
39992
|
+
});
|
|
39993
|
+
}
|
|
39994
|
+
});
|
|
39995
|
+
|
|
39996
|
+
// src/rules/rust/todo-macro.ts
|
|
39997
|
+
function collectMacroIssues(node, testScopes, issues) {
|
|
39998
|
+
if (node.type === "macro_invocation") {
|
|
39999
|
+
const text = node.text;
|
|
40000
|
+
const m = text.match(/^([A-Za-z_][A-Za-z0-9_]*)/);
|
|
40001
|
+
const macroName = m?.[1] ?? "";
|
|
40002
|
+
if (TODO_MACROS.has(macroName)) {
|
|
40003
|
+
if (!isInsideMacroDefinition(node) && !isInsideTestFunction(node, testScopes)) {
|
|
40004
|
+
issues.push({
|
|
40005
|
+
ruleId: "rust/todo-macro",
|
|
40006
|
+
category: "logic",
|
|
40007
|
+
severity: "medium",
|
|
40008
|
+
aiSpecific: true,
|
|
40009
|
+
message: `'${macroName}!()' in production code \u2014 both expand to panic!()`,
|
|
40010
|
+
line: node.startPosition.row + 1,
|
|
40011
|
+
column: node.startPosition.column,
|
|
40012
|
+
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.`
|
|
40013
|
+
});
|
|
40014
|
+
}
|
|
40015
|
+
}
|
|
40016
|
+
}
|
|
40017
|
+
for (let i = 0; i < node.namedChildCount; i++) {
|
|
40018
|
+
const child = node.namedChild(i);
|
|
40019
|
+
if (child) collectMacroIssues(child, testScopes, issues);
|
|
40020
|
+
}
|
|
40021
|
+
}
|
|
40022
|
+
function isInsideMacroDefinition(node) {
|
|
40023
|
+
for (let p = node.parent; p; p = p.parent) {
|
|
40024
|
+
if (p.type === "macro_definition") return true;
|
|
40025
|
+
if (p.type === "source_file") return false;
|
|
40026
|
+
}
|
|
40027
|
+
return false;
|
|
40028
|
+
}
|
|
40029
|
+
function isInsideTestFunction(node, testScopes) {
|
|
40030
|
+
for (let p = node.parent; p; p = p.parent) {
|
|
40031
|
+
if (p.type === "function_item") {
|
|
40032
|
+
const nameField = p.childForFieldName("name");
|
|
40033
|
+
const name = nameField?.text;
|
|
40034
|
+
if (name && testScopes.has(name)) return true;
|
|
40035
|
+
if (p.text.startsWith("#[test]") || p.text.startsWith("#[cfg(test)]")) return true;
|
|
40036
|
+
return false;
|
|
40037
|
+
}
|
|
40038
|
+
if (p.type === "source_file") return false;
|
|
40039
|
+
}
|
|
40040
|
+
return false;
|
|
40041
|
+
}
|
|
40042
|
+
var TODO_MACROS, rustTodoMacroRule;
|
|
40043
|
+
var init_todo_macro = __esm({
|
|
40044
|
+
"src/rules/rust/todo-macro.ts"() {
|
|
40045
|
+
"use strict";
|
|
40046
|
+
init_rule();
|
|
40047
|
+
init_parser_rust();
|
|
40048
|
+
TODO_MACROS = /* @__PURE__ */ new Set(["todo", "unimplemented", "todo_unimplemented"]);
|
|
40049
|
+
rustTodoMacroRule = createRule({
|
|
40050
|
+
id: "rust/todo-macro",
|
|
40051
|
+
category: "logic",
|
|
40052
|
+
severity: "medium",
|
|
40053
|
+
aiSpecific: true,
|
|
40054
|
+
description: "todo!() / unimplemented!() macro invocation in production code",
|
|
40055
|
+
create(_context) {
|
|
40056
|
+
return {};
|
|
40057
|
+
},
|
|
40058
|
+
analyze(_context, facts) {
|
|
40059
|
+
const issues = [];
|
|
40060
|
+
if (!facts.v2?.rustFile) return issues;
|
|
40061
|
+
const source = facts.v2._source ?? "";
|
|
40062
|
+
if (!source) return issues;
|
|
40063
|
+
const tree = parseRust(source);
|
|
40064
|
+
if (!tree) return issues;
|
|
40065
|
+
const testScopes = /* @__PURE__ */ new Set();
|
|
40066
|
+
for (const fn of facts.v2.rustFile.functions) {
|
|
40067
|
+
if (fn.inTestConfig && fn.name) testScopes.add(fn.name);
|
|
40068
|
+
}
|
|
40069
|
+
collectMacroIssues(tree.rootNode, testScopes, issues);
|
|
40070
|
+
return issues;
|
|
40071
|
+
}
|
|
40072
|
+
});
|
|
40073
|
+
}
|
|
40074
|
+
});
|
|
40075
|
+
|
|
40076
|
+
// src/rules/rust/unused-pub-fn.ts
|
|
40077
|
+
function collectReferencedNames(source) {
|
|
40078
|
+
const out = /* @__PURE__ */ new Set();
|
|
40079
|
+
for (const m of source.matchAll(/\b([A-Za-z_][A-Za-z0-9_]*)\b/g)) {
|
|
40080
|
+
out.add(m[1]);
|
|
40081
|
+
}
|
|
40082
|
+
return out;
|
|
40083
|
+
}
|
|
40084
|
+
var API_CONVENTION_NAMES, rustUnusedPubFnRule;
|
|
40085
|
+
var init_unused_pub_fn = __esm({
|
|
40086
|
+
"src/rules/rust/unused-pub-fn.ts"() {
|
|
40087
|
+
"use strict";
|
|
40088
|
+
init_rule();
|
|
40089
|
+
API_CONVENTION_NAMES = /* @__PURE__ */ new Set([
|
|
40090
|
+
"new",
|
|
40091
|
+
"default",
|
|
40092
|
+
"from",
|
|
40093
|
+
"from_str",
|
|
40094
|
+
"from_iter",
|
|
40095
|
+
"try_from",
|
|
40096
|
+
"into",
|
|
40097
|
+
"into_iter",
|
|
40098
|
+
"try_into",
|
|
40099
|
+
"as_ref",
|
|
40100
|
+
"as_mut",
|
|
40101
|
+
"clone",
|
|
40102
|
+
"fmt",
|
|
40103
|
+
"eq",
|
|
40104
|
+
"hash",
|
|
40105
|
+
"partial_cmp",
|
|
40106
|
+
"cmp",
|
|
40107
|
+
"ord",
|
|
40108
|
+
"partial_eq"
|
|
40109
|
+
]);
|
|
40110
|
+
rustUnusedPubFnRule = createRule({
|
|
40111
|
+
id: "rust/unused-pub-fn",
|
|
40112
|
+
category: "logic",
|
|
40113
|
+
severity: "low",
|
|
40114
|
+
aiSpecific: true,
|
|
40115
|
+
description: "Public function in a Rust file that has no in-file references",
|
|
40116
|
+
create(_context) {
|
|
40117
|
+
return {};
|
|
40118
|
+
},
|
|
40119
|
+
analyze(_context, facts) {
|
|
40120
|
+
const issues = [];
|
|
40121
|
+
if (!facts.v2?.rustFile) return issues;
|
|
40122
|
+
const rust = facts.v2.rustFile;
|
|
40123
|
+
const referenced = collectReferencedNames(facts.v2._source ?? "");
|
|
40124
|
+
for (const fn of rust.functions) {
|
|
40125
|
+
if (!fn.isPublic) continue;
|
|
40126
|
+
if (API_CONVENTION_NAMES.has(fn.name)) continue;
|
|
40127
|
+
if (fn.inTestConfig) continue;
|
|
40128
|
+
if (referenced.has(fn.name)) continue;
|
|
40129
|
+
issues.push({
|
|
40130
|
+
ruleId: "rust/unused-pub-fn",
|
|
40131
|
+
category: "logic",
|
|
40132
|
+
severity: "low",
|
|
40133
|
+
aiSpecific: true,
|
|
40134
|
+
message: `Public function '${fn.name}' is not referenced anywhere in the file`,
|
|
40135
|
+
line: fn.line,
|
|
40136
|
+
column: fn.column,
|
|
40137
|
+
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.`
|
|
40138
|
+
});
|
|
40139
|
+
}
|
|
40140
|
+
return issues;
|
|
40141
|
+
}
|
|
40142
|
+
});
|
|
40143
|
+
}
|
|
40144
|
+
});
|
|
40145
|
+
|
|
40146
|
+
// src/rules/rust/unwrap-in-production.ts
|
|
40147
|
+
function collectUnwrapIssues(node, testScopes, issues) {
|
|
40148
|
+
if (node.type === "call_expression") {
|
|
40149
|
+
const fn = node.childForFieldName("function");
|
|
40150
|
+
if (fn && fn.type === "field_expression") {
|
|
40151
|
+
const field = fn.childForFieldName("field");
|
|
40152
|
+
if (field && field.type === "field_identifier" && UNWRAP_METHODS.has(field.text)) {
|
|
40153
|
+
if (!isInsideTestFunction2(node, testScopes)) {
|
|
40154
|
+
issues.push({
|
|
40155
|
+
ruleId: "rust/unwrap-in-production",
|
|
40156
|
+
category: "logic",
|
|
40157
|
+
severity: "medium",
|
|
40158
|
+
aiSpecific: true,
|
|
40159
|
+
message: `'.${field.text}()' called in production code \u2014 panic risk on Err/None`,
|
|
40160
|
+
line: node.startPosition.row + 1,
|
|
40161
|
+
column: node.startPosition.column,
|
|
40162
|
+
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.`
|
|
40163
|
+
});
|
|
40164
|
+
}
|
|
40165
|
+
}
|
|
40166
|
+
}
|
|
40167
|
+
}
|
|
40168
|
+
for (let i = 0; i < node.namedChildCount; i++) {
|
|
40169
|
+
const child = node.namedChild(i);
|
|
40170
|
+
if (child) collectUnwrapIssues(child, testScopes, issues);
|
|
40171
|
+
}
|
|
40172
|
+
}
|
|
40173
|
+
function isInsideTestFunction2(node, testScopes) {
|
|
40174
|
+
for (let p = node.parent; p; p = p.parent) {
|
|
40175
|
+
if (p.type === "function_item") {
|
|
40176
|
+
const nameField = p.childForFieldName("name");
|
|
40177
|
+
const name = nameField?.text;
|
|
40178
|
+
if (name && testScopes.has(name)) return true;
|
|
40179
|
+
if (p.text.startsWith("#[test]") || p.text.startsWith("#[cfg(test)]")) return true;
|
|
40180
|
+
return false;
|
|
40181
|
+
}
|
|
40182
|
+
if (p.type === "source_file") return false;
|
|
40183
|
+
}
|
|
40184
|
+
return false;
|
|
40185
|
+
}
|
|
40186
|
+
var UNWRAP_METHODS, rustUnwrapInProductionRule;
|
|
40187
|
+
var init_unwrap_in_production = __esm({
|
|
40188
|
+
"src/rules/rust/unwrap-in-production.ts"() {
|
|
40189
|
+
"use strict";
|
|
40190
|
+
init_rule();
|
|
40191
|
+
init_parser_rust();
|
|
40192
|
+
UNWRAP_METHODS = /* @__PURE__ */ new Set(["unwrap", "expect", "unwrap_or_else"]);
|
|
40193
|
+
rustUnwrapInProductionRule = createRule({
|
|
40194
|
+
id: "rust/unwrap-in-production",
|
|
40195
|
+
category: "logic",
|
|
40196
|
+
severity: "medium",
|
|
40197
|
+
aiSpecific: true,
|
|
40198
|
+
description: ".unwrap() / .expect() called outside of #[cfg(test)] / #[test] scope",
|
|
40199
|
+
create(_context) {
|
|
40200
|
+
return {};
|
|
40201
|
+
},
|
|
40202
|
+
analyze(_context, facts) {
|
|
40203
|
+
const issues = [];
|
|
40204
|
+
if (!facts.v2?.rustFile) return issues;
|
|
40205
|
+
const source = facts.v2._source ?? "";
|
|
40206
|
+
if (!source) return issues;
|
|
40207
|
+
const tree = parseRust(source);
|
|
40208
|
+
if (!tree) return issues;
|
|
40209
|
+
const testScopes = /* @__PURE__ */ new Set();
|
|
40210
|
+
for (const fn of facts.v2.rustFile.functions) {
|
|
40211
|
+
if (fn.inTestConfig && fn.name) testScopes.add(fn.name);
|
|
40212
|
+
}
|
|
40213
|
+
collectUnwrapIssues(tree.rootNode, testScopes, issues);
|
|
40214
|
+
return issues;
|
|
40215
|
+
}
|
|
40216
|
+
});
|
|
40217
|
+
}
|
|
40218
|
+
});
|
|
40219
|
+
|
|
39319
40220
|
// src/rules/security/dangerous-cors.ts
|
|
39320
40221
|
function scanForWildcardCors(source) {
|
|
39321
40222
|
const hits = [];
|
|
@@ -40906,6 +41807,251 @@ var init_weak_assertion = __esm({
|
|
|
40906
41807
|
}
|
|
40907
41808
|
});
|
|
40908
41809
|
|
|
41810
|
+
// src/rules/ts/enum-vs-as-const.ts
|
|
41811
|
+
var ENUM_DECL_REGEX, tsEnumVsAsConstRule;
|
|
41812
|
+
var init_enum_vs_as_const = __esm({
|
|
41813
|
+
"src/rules/ts/enum-vs-as-const.ts"() {
|
|
41814
|
+
"use strict";
|
|
41815
|
+
init_rule();
|
|
41816
|
+
ENUM_DECL_REGEX = /^[ \t]*(?:export\s+)?(?:const\s+)?enum\s+[A-Z_][A-Za-z0-9_]*\s*\{/gm;
|
|
41817
|
+
tsEnumVsAsConstRule = createRule({
|
|
41818
|
+
id: "ts/enum-vs-as-const",
|
|
41819
|
+
category: "typo",
|
|
41820
|
+
severity: "low",
|
|
41821
|
+
aiSpecific: true,
|
|
41822
|
+
description: "Uses `enum` \u2014 modern TS prefers `as const` objects",
|
|
41823
|
+
create(_context) {
|
|
41824
|
+
return {};
|
|
41825
|
+
},
|
|
41826
|
+
analyze(_context, facts) {
|
|
41827
|
+
const issues = [];
|
|
41828
|
+
const source = facts.v2?._source;
|
|
41829
|
+
if (!source) return issues;
|
|
41830
|
+
let match;
|
|
41831
|
+
ENUM_DECL_REGEX.lastIndex = 0;
|
|
41832
|
+
while ((match = ENUM_DECL_REGEX.exec(source)) !== null) {
|
|
41833
|
+
const line = source.slice(0, match.index).split("\n").length;
|
|
41834
|
+
issues.push({
|
|
41835
|
+
ruleId: "ts/enum-vs-as-const",
|
|
41836
|
+
category: "typo",
|
|
41837
|
+
severity: "low",
|
|
41838
|
+
aiSpecific: true,
|
|
41839
|
+
message: `'enum' is an AI / older-TS pattern \u2014 prefer 'as const' for a frozen object literal`,
|
|
41840
|
+
line,
|
|
41841
|
+
column: match[0].indexOf("enum") + 1,
|
|
41842
|
+
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.'
|
|
41843
|
+
});
|
|
41844
|
+
}
|
|
41845
|
+
return issues;
|
|
41846
|
+
}
|
|
41847
|
+
});
|
|
41848
|
+
}
|
|
41849
|
+
});
|
|
41850
|
+
|
|
41851
|
+
// src/rules/ts/excessive-type-assertion.ts
|
|
41852
|
+
var DEFAULT_MAX, FN_DECL_REGEX, AS_REGEX, tsExcessiveTypeAssertionRule;
|
|
41853
|
+
var init_excessive_type_assertion = __esm({
|
|
41854
|
+
"src/rules/ts/excessive-type-assertion.ts"() {
|
|
41855
|
+
"use strict";
|
|
41856
|
+
init_rule();
|
|
41857
|
+
DEFAULT_MAX = 3;
|
|
41858
|
+
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;
|
|
41859
|
+
AS_REGEX = /(?<![\w$])as\s+(?!const)([A-Z][\w$.,<>\[\]|&]*)/g;
|
|
41860
|
+
tsExcessiveTypeAssertionRule = createRule({
|
|
41861
|
+
id: "ts/excessive-type-assertion",
|
|
41862
|
+
category: "typo",
|
|
41863
|
+
severity: "low",
|
|
41864
|
+
aiSpecific: true,
|
|
41865
|
+
description: "Function with >3 `as` type assertions \u2014 likely AI fighting the type system",
|
|
41866
|
+
create(_context) {
|
|
41867
|
+
return { maxAssertionsPerFunction: DEFAULT_MAX };
|
|
41868
|
+
},
|
|
41869
|
+
analyze(context, facts) {
|
|
41870
|
+
const issues = [];
|
|
41871
|
+
const source = facts.v2?._source;
|
|
41872
|
+
if (!source) return issues;
|
|
41873
|
+
let match;
|
|
41874
|
+
FN_DECL_REGEX.lastIndex = 0;
|
|
41875
|
+
while ((match = FN_DECL_REGEX.exec(source)) !== null) {
|
|
41876
|
+
const startIdx = match.index;
|
|
41877
|
+
const openBraceIdx = source.indexOf("{", startIdx);
|
|
41878
|
+
if (openBraceIdx < 0) continue;
|
|
41879
|
+
let depth = 1;
|
|
41880
|
+
let i = openBraceIdx + 1;
|
|
41881
|
+
while (i < source.length && depth > 0) {
|
|
41882
|
+
const ch = source[i];
|
|
41883
|
+
if (ch === "{") depth++;
|
|
41884
|
+
else if (ch === "}") depth--;
|
|
41885
|
+
i++;
|
|
41886
|
+
}
|
|
41887
|
+
const body = source.slice(openBraceIdx, i);
|
|
41888
|
+
const line = source.slice(0, startIdx).split("\n").length;
|
|
41889
|
+
let asCount = 0;
|
|
41890
|
+
const seen = /* @__PURE__ */ new Set();
|
|
41891
|
+
let asMatch;
|
|
41892
|
+
AS_REGEX.lastIndex = 0;
|
|
41893
|
+
while ((asMatch = AS_REGEX.exec(body)) !== null) {
|
|
41894
|
+
const captured = asMatch[1];
|
|
41895
|
+
if (seen.has(captured)) continue;
|
|
41896
|
+
seen.add(captured);
|
|
41897
|
+
asCount++;
|
|
41898
|
+
}
|
|
41899
|
+
if (asCount > context.maxAssertionsPerFunction) {
|
|
41900
|
+
issues.push({
|
|
41901
|
+
ruleId: "ts/excessive-type-assertion",
|
|
41902
|
+
category: "typo",
|
|
41903
|
+
severity: "low",
|
|
41904
|
+
aiSpecific: true,
|
|
41905
|
+
message: `Function has ${asCount} 'as' assertions (max ${context.maxAssertionsPerFunction}) \u2014 likely AI fighting the type system`,
|
|
41906
|
+
line,
|
|
41907
|
+
column: 1,
|
|
41908
|
+
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."
|
|
41909
|
+
});
|
|
41910
|
+
}
|
|
41911
|
+
}
|
|
41912
|
+
return issues;
|
|
41913
|
+
}
|
|
41914
|
+
});
|
|
41915
|
+
}
|
|
41916
|
+
});
|
|
41917
|
+
|
|
41918
|
+
// src/rules/ts/import-type-misuse.ts
|
|
41919
|
+
var INLINE_TYPE_IMPORT_REGEX, tsImportTypeMisuseRule;
|
|
41920
|
+
var init_import_type_misuse = __esm({
|
|
41921
|
+
"src/rules/ts/import-type-misuse.ts"() {
|
|
41922
|
+
"use strict";
|
|
41923
|
+
init_rule();
|
|
41924
|
+
INLINE_TYPE_IMPORT_REGEX = /^[ \t]*import\s*\{[^}]*\btype\s+[A-Za-z_]/gm;
|
|
41925
|
+
tsImportTypeMisuseRule = createRule({
|
|
41926
|
+
id: "ts/import-type-misuse",
|
|
41927
|
+
category: "typo",
|
|
41928
|
+
severity: "low",
|
|
41929
|
+
aiSpecific: true,
|
|
41930
|
+
description: "Inline `import { type X }` \u2014 prefer `import type { X }` for clarity",
|
|
41931
|
+
create(_context) {
|
|
41932
|
+
return {};
|
|
41933
|
+
},
|
|
41934
|
+
analyze(_context, facts) {
|
|
41935
|
+
const issues = [];
|
|
41936
|
+
const source = facts.v2?._source;
|
|
41937
|
+
if (!source) return issues;
|
|
41938
|
+
let match;
|
|
41939
|
+
INLINE_TYPE_IMPORT_REGEX.lastIndex = 0;
|
|
41940
|
+
while ((match = INLINE_TYPE_IMPORT_REGEX.exec(source)) !== null) {
|
|
41941
|
+
const line = source.slice(0, match.index).split("\n").length;
|
|
41942
|
+
issues.push({
|
|
41943
|
+
ruleId: "ts/import-type-misuse",
|
|
41944
|
+
category: "typo",
|
|
41945
|
+
severity: "low",
|
|
41946
|
+
aiSpecific: true,
|
|
41947
|
+
message: "Inline `type` in a value import \u2014 split into a separate `import type` statement",
|
|
41948
|
+
line,
|
|
41949
|
+
column: match[0].indexOf("type") + 1,
|
|
41950
|
+
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.'
|
|
41951
|
+
});
|
|
41952
|
+
}
|
|
41953
|
+
return issues;
|
|
41954
|
+
}
|
|
41955
|
+
});
|
|
41956
|
+
}
|
|
41957
|
+
});
|
|
41958
|
+
|
|
41959
|
+
// src/rules/ts/never-vs-unknown.ts
|
|
41960
|
+
var NEVER_RETURN_REGEX, THROW_OR_LOOP_REGEX, tsNeverVsUnknownRule;
|
|
41961
|
+
var init_never_vs_unknown = __esm({
|
|
41962
|
+
"src/rules/ts/never-vs-unknown.ts"() {
|
|
41963
|
+
"use strict";
|
|
41964
|
+
init_rule();
|
|
41965
|
+
NEVER_RETURN_REGEX = /^[ \t]*(?:export\s+)?(?:async\s+)?function\s+([A-Za-z_$][\w$]*)[^{]*:\s*(?:Promise<)?never\b[^{]*\{/gm;
|
|
41966
|
+
THROW_OR_LOOP_REGEX = /\b(?:throw\b|while\s*\(|for\s*\(|process\.exit\b|System\.exit\b)/;
|
|
41967
|
+
tsNeverVsUnknownRule = createRule({
|
|
41968
|
+
id: "ts/never-vs-unknown",
|
|
41969
|
+
category: "typo",
|
|
41970
|
+
severity: "low",
|
|
41971
|
+
aiSpecific: true,
|
|
41972
|
+
description: "Return type `: never` but body has no throw / loop / exit \u2014 likely AI misuse",
|
|
41973
|
+
create(_context) {
|
|
41974
|
+
return {};
|
|
41975
|
+
},
|
|
41976
|
+
analyze(_context, facts) {
|
|
41977
|
+
const issues = [];
|
|
41978
|
+
const source = facts.v2?._source;
|
|
41979
|
+
if (!source) return issues;
|
|
41980
|
+
let match;
|
|
41981
|
+
NEVER_RETURN_REGEX.lastIndex = 0;
|
|
41982
|
+
while ((match = NEVER_RETURN_REGEX.exec(source)) !== null) {
|
|
41983
|
+
const fnName = match[1];
|
|
41984
|
+
const startIdx = match.index;
|
|
41985
|
+
const line = source.slice(0, startIdx).split("\n").length;
|
|
41986
|
+
const openBraceIdx = source.indexOf("{", startIdx);
|
|
41987
|
+
if (openBraceIdx < 0) continue;
|
|
41988
|
+
let depth = 1;
|
|
41989
|
+
let i = openBraceIdx + 1;
|
|
41990
|
+
while (i < source.length && depth > 0) {
|
|
41991
|
+
const ch = source[i];
|
|
41992
|
+
if (ch === "{") depth++;
|
|
41993
|
+
else if (ch === "}") depth--;
|
|
41994
|
+
i++;
|
|
41995
|
+
}
|
|
41996
|
+
const body = source.slice(openBraceIdx, i);
|
|
41997
|
+
if (THROW_OR_LOOP_REGEX.test(body)) continue;
|
|
41998
|
+
issues.push({
|
|
41999
|
+
ruleId: "ts/never-vs-unknown",
|
|
42000
|
+
category: "typo",
|
|
42001
|
+
severity: "low",
|
|
42002
|
+
aiSpecific: true,
|
|
42003
|
+
message: `Function '${fnName}' returns 'never' but its body has no throw, loop, or exit \u2014 likely AI misuse`,
|
|
42004
|
+
line,
|
|
42005
|
+
column: match[0].indexOf("never") + 1,
|
|
42006
|
+
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.'
|
|
42007
|
+
});
|
|
42008
|
+
}
|
|
42009
|
+
return issues;
|
|
42010
|
+
}
|
|
42011
|
+
});
|
|
42012
|
+
}
|
|
42013
|
+
});
|
|
42014
|
+
|
|
42015
|
+
// src/rules/ts/optional-chain-overuse.ts
|
|
42016
|
+
var DEFAULT_MIN_CHAIN_LENGTH, tsOptionalChainOveruseRule;
|
|
42017
|
+
var init_optional_chain_overuse = __esm({
|
|
42018
|
+
"src/rules/ts/optional-chain-overuse.ts"() {
|
|
42019
|
+
"use strict";
|
|
42020
|
+
init_rule();
|
|
42021
|
+
DEFAULT_MIN_CHAIN_LENGTH = 5;
|
|
42022
|
+
tsOptionalChainOveruseRule = createRule({
|
|
42023
|
+
id: "ts/optional-chain-overuse",
|
|
42024
|
+
category: "logic",
|
|
42025
|
+
severity: "low",
|
|
42026
|
+
aiSpecific: true,
|
|
42027
|
+
description: "Optional chaining (?.) used 5+ times in a single chain \u2014 AI tends to chain rather than narrow",
|
|
42028
|
+
create(_context) {
|
|
42029
|
+
return { minChainLength: DEFAULT_MIN_CHAIN_LENGTH };
|
|
42030
|
+
},
|
|
42031
|
+
analyze(context, facts) {
|
|
42032
|
+
const issues = [];
|
|
42033
|
+
const expressions = facts.v2.logic?.logicalExpressions;
|
|
42034
|
+
if (!expressions) return issues;
|
|
42035
|
+
for (const expression of expressions) {
|
|
42036
|
+
if (expression.depth >= context.minChainLength && expression.isOptionalChainLike) {
|
|
42037
|
+
issues.push({
|
|
42038
|
+
ruleId: "ts/optional-chain-overuse",
|
|
42039
|
+
category: "logic",
|
|
42040
|
+
severity: "low",
|
|
42041
|
+
aiSpecific: true,
|
|
42042
|
+
message: `Optional chain depth ${expression.depth} \u2014 break with an intermediate variable or guard clause`,
|
|
42043
|
+
line: expression.line,
|
|
42044
|
+
column: expression.column,
|
|
42045
|
+
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."
|
|
42046
|
+
});
|
|
42047
|
+
}
|
|
42048
|
+
}
|
|
42049
|
+
return issues;
|
|
42050
|
+
}
|
|
42051
|
+
});
|
|
42052
|
+
}
|
|
42053
|
+
});
|
|
42054
|
+
|
|
40909
42055
|
// src/rules/typo/calc-fontsize.ts
|
|
40910
42056
|
var FONT_SIZE_RE, calcFontsizeRule;
|
|
40911
42057
|
var init_calc_fontsize = __esm({
|
|
@@ -42010,7 +43156,7 @@ function spanEnd(node) {
|
|
|
42010
43156
|
}
|
|
42011
43157
|
return void 0;
|
|
42012
43158
|
}
|
|
42013
|
-
function
|
|
43159
|
+
function buildLineOffsets2(source) {
|
|
42014
43160
|
const offsets = [0];
|
|
42015
43161
|
let byteOffset = 0;
|
|
42016
43162
|
for (let i = 0; i < source.length; i++) {
|
|
@@ -44011,9 +45157,60 @@ function buildV2Facts(facts, source, ext, framework, config, templateClassNames
|
|
|
44011
45157
|
})),
|
|
44012
45158
|
disabledRules: extractDisabledRules(source),
|
|
44013
45159
|
templateClassNames,
|
|
45160
|
+
// v0.18.9 — populate the Rust AST record when the file is `.rs`.
|
|
45161
|
+
// Calling `parseRustFile` here keeps the dead-code detector's
|
|
45162
|
+
// import-binding pass a pure function over the same source the
|
|
45163
|
+
// walker saw. The native-binding guard lives inside
|
|
45164
|
+
// `parseRustFile` (returns an empty record when tree-sitter is
|
|
45165
|
+
// unavailable).
|
|
45166
|
+
rustFile: buildRustFileRecord(facts.filePath, source),
|
|
44014
45167
|
_source: source
|
|
44015
45168
|
};
|
|
44016
45169
|
}
|
|
45170
|
+
function buildRustFileRecord(filePath, source) {
|
|
45171
|
+
if (!filePath.toLowerCase().endsWith(".rs")) return void 0;
|
|
45172
|
+
const structure = parseRustFile(filePath, source);
|
|
45173
|
+
return {
|
|
45174
|
+
imports: structure.imports.map((i) => ({
|
|
45175
|
+
path: i.path,
|
|
45176
|
+
names: i.names.map((n) => ({ name: n.name, ...n.alias ? { alias: n.alias } : {} })),
|
|
45177
|
+
isGlob: i.isGlob,
|
|
45178
|
+
line: i.line,
|
|
45179
|
+
column: i.column
|
|
45180
|
+
})),
|
|
45181
|
+
functions: structure.functions.map((f) => ({
|
|
45182
|
+
name: f.name,
|
|
45183
|
+
line: f.line,
|
|
45184
|
+
column: f.column,
|
|
45185
|
+
isPublic: f.isPublic,
|
|
45186
|
+
isMethod: f.isMethod,
|
|
45187
|
+
...f.receiver ? { receiver: f.receiver } : {},
|
|
45188
|
+
bodyLines: f.bodyLines,
|
|
45189
|
+
inTestConfig: f.inTestConfig
|
|
45190
|
+
})),
|
|
45191
|
+
structs: structure.structs.map((s) => ({
|
|
45192
|
+
name: s.name,
|
|
45193
|
+
line: s.line,
|
|
45194
|
+
column: s.column,
|
|
45195
|
+
isPublic: s.isPublic,
|
|
45196
|
+
isDerive: s.isDerive,
|
|
45197
|
+
derives: [...s.derives]
|
|
45198
|
+
})),
|
|
45199
|
+
traits: structure.traits.map((t) => ({
|
|
45200
|
+
name: t.name,
|
|
45201
|
+
line: t.line,
|
|
45202
|
+
column: t.column,
|
|
45203
|
+
isPublic: t.isPublic
|
|
45204
|
+
})),
|
|
45205
|
+
impls: structure.impls.map((ip) => ({
|
|
45206
|
+
...ip.trait ? { trait: ip.trait } : {},
|
|
45207
|
+
type: ip.type,
|
|
45208
|
+
methods: [...ip.methods],
|
|
45209
|
+
line: ip.line,
|
|
45210
|
+
column: ip.column
|
|
45211
|
+
}))
|
|
45212
|
+
};
|
|
45213
|
+
}
|
|
44017
45214
|
function splitFilePath(filePath) {
|
|
44018
45215
|
const baseName2 = filePath.split("/").pop() ?? filePath;
|
|
44019
45216
|
const dotIdx = baseName2.lastIndexOf(".");
|
|
@@ -44028,6 +45225,7 @@ var init_v2_build = __esm({
|
|
|
44028
45225
|
"src/engine/visitors/v2-build.ts"() {
|
|
44029
45226
|
"use strict";
|
|
44030
45227
|
init_scan_helpers();
|
|
45228
|
+
init_rust();
|
|
44031
45229
|
TAILWIND_COLOR_RE = /^(?:bg|text|border|ring|from|to|via|fill|stroke)-([a-z]+-\d+|white|black|transparent|current|\[.+?\])$/;
|
|
44032
45230
|
TAILWIND_SPACING_RE = /^(?:[pm][xytrbl]?|gap|space-[xy])-(\d+(?:\.\d+)?)$/;
|
|
44033
45231
|
TAILWIND_RADIUS_RE = /^(?:rounded(?:-[a-z]+)?)-(.+)$/;
|
|
@@ -44060,7 +45258,7 @@ function mergeTemplateClassNames(filePath, source, facts, templateClassNames) {
|
|
|
44060
45258
|
}
|
|
44061
45259
|
}
|
|
44062
45260
|
function extractFacts(filePath, ast, source, supportsRsc = true, framework = "react", config) {
|
|
44063
|
-
const lineOffsets =
|
|
45261
|
+
const lineOffsets = buildLineOffsets2(source);
|
|
44064
45262
|
const isTypeScript = /\.tsx?$/i.test(filePath);
|
|
44065
45263
|
const NON_JSX_FRAMEWORKS = /* @__PURE__ */ new Set(["vue", "svelte", "astro"]);
|
|
44066
45264
|
const facts = {
|
|
@@ -44348,7 +45546,7 @@ var init_naturalness_anomaly = __esm({
|
|
|
44348
45546
|
const issues = [];
|
|
44349
45547
|
const source = facts.v2?._source;
|
|
44350
45548
|
if (!source) return issues;
|
|
44351
|
-
const lineOffsets =
|
|
45549
|
+
const lineOffsets = buildLineOffsets2(source);
|
|
44352
45550
|
const components = facts.v2?.components ?? [];
|
|
44353
45551
|
const perComponentMetrics = components.filter((c) => c.loc > 0).map(
|
|
44354
45552
|
(c) => computeNaturalnessForRange(source, lineOffsets, c.line, c.line + c.loc - 1, context.model)
|
|
@@ -44995,6 +46193,10 @@ var init_builtins = __esm({
|
|
|
44995
46193
|
init_expired_code_example();
|
|
44996
46194
|
init_stale_function_reference();
|
|
44997
46195
|
init_stale_package_reference();
|
|
46196
|
+
init_identical_block();
|
|
46197
|
+
init_error_wrap_without_context();
|
|
46198
|
+
init_nil_slice_vs_empty();
|
|
46199
|
+
init_struct_tag_inconsistency();
|
|
44998
46200
|
init_gap_monopoly();
|
|
44999
46201
|
init_math_element_uniformity();
|
|
45000
46202
|
init_math_grid_uniformity();
|
|
@@ -45004,7 +46206,6 @@ var init_builtins = __esm({
|
|
|
45004
46206
|
init_ghost_defensive();
|
|
45005
46207
|
init_heaps_deviation();
|
|
45006
46208
|
init_key_prop_missing();
|
|
45007
|
-
init_ks_distribution_shift();
|
|
45008
46209
|
init_math_any_density();
|
|
45009
46210
|
init_math_console_log_storm();
|
|
45010
46211
|
init_math_gini_class_usage();
|
|
@@ -45019,6 +46220,10 @@ var init_builtins = __esm({
|
|
|
45019
46220
|
init_halstead_anomaly();
|
|
45020
46221
|
init_terminology_drift();
|
|
45021
46222
|
init_ux_pattern_fragmentation();
|
|
46223
|
+
init_stringly_typed();
|
|
46224
|
+
init_todo_macro();
|
|
46225
|
+
init_unused_pub_fn();
|
|
46226
|
+
init_unwrap_in_production();
|
|
45022
46227
|
init_dangerous_cors();
|
|
45023
46228
|
init_eval();
|
|
45024
46229
|
init_exposed_env_var();
|
|
@@ -45034,6 +46239,11 @@ var init_builtins = __esm({
|
|
|
45034
46239
|
init_fake_placeholder();
|
|
45035
46240
|
init_missing_edge_case();
|
|
45036
46241
|
init_weak_assertion();
|
|
46242
|
+
init_enum_vs_as_const();
|
|
46243
|
+
init_excessive_type_assertion();
|
|
46244
|
+
init_import_type_misuse();
|
|
46245
|
+
init_never_vs_unknown();
|
|
46246
|
+
init_optional_chain_overuse();
|
|
45037
46247
|
init_calc_fontsize();
|
|
45038
46248
|
init_calc_raw_px();
|
|
45039
46249
|
init_clamp_offscale();
|
|
@@ -45096,6 +46306,10 @@ var init_builtins = __esm({
|
|
|
45096
46306
|
expiredCodeExampleRule,
|
|
45097
46307
|
staleFunctionReferenceRule,
|
|
45098
46308
|
stalePackageReferenceRule,
|
|
46309
|
+
dupIdenticalBlockRule,
|
|
46310
|
+
goErrorWrapWithoutContextRule,
|
|
46311
|
+
goNilSliceVsEmptyRule,
|
|
46312
|
+
goStructTagInconsistencyRule,
|
|
45099
46313
|
gapMonopolyRule,
|
|
45100
46314
|
mathElementUniformityRule,
|
|
45101
46315
|
mathGridUniformityRule,
|
|
@@ -45105,7 +46319,6 @@ var init_builtins = __esm({
|
|
|
45105
46319
|
ghostDefensiveRule,
|
|
45106
46320
|
heapsDeviationRule,
|
|
45107
46321
|
keyPropMissingRule,
|
|
45108
|
-
ksDistributionShiftRule,
|
|
45109
46322
|
mathAnyDensityRule,
|
|
45110
46323
|
mathConsoleLogStormRule,
|
|
45111
46324
|
mathGiniClassUsageRule,
|
|
@@ -45120,6 +46333,10 @@ var init_builtins = __esm({
|
|
|
45120
46333
|
halsteadAnomalyRule,
|
|
45121
46334
|
terminologyDriftRule,
|
|
45122
46335
|
uxPatternFragmentationRule,
|
|
46336
|
+
rustStringlyTypedRule,
|
|
46337
|
+
rustTodoMacroRule,
|
|
46338
|
+
rustUnusedPubFnRule,
|
|
46339
|
+
rustUnwrapInProductionRule,
|
|
45123
46340
|
dangerousCorsRule,
|
|
45124
46341
|
evalRule,
|
|
45125
46342
|
exposedEnvVarRule,
|
|
@@ -45135,6 +46352,11 @@ var init_builtins = __esm({
|
|
|
45135
46352
|
fakePlaceholderRule,
|
|
45136
46353
|
missingEdgeCaseRule,
|
|
45137
46354
|
weakAssertionRule,
|
|
46355
|
+
tsEnumVsAsConstRule,
|
|
46356
|
+
tsExcessiveTypeAssertionRule,
|
|
46357
|
+
tsImportTypeMisuseRule,
|
|
46358
|
+
tsNeverVsUnknownRule,
|
|
46359
|
+
tsOptionalChainOveruseRule,
|
|
45138
46360
|
calcFontsizeRule,
|
|
45139
46361
|
calcRawPxRule,
|
|
45140
46362
|
clampOffscaleRule,
|
|
@@ -47097,6 +48319,22 @@ var init_registry = __esm({
|
|
|
47097
48319
|
if (!filter) return list;
|
|
47098
48320
|
return list.filter((r) => filter.kind === "ai" ? r.aiSpecific : !r.aiSpecific);
|
|
47099
48321
|
}
|
|
48322
|
+
/** v0.18.8: remove every rule where `predicate(rule)` returns true.
|
|
48323
|
+
* Used by focused calibration scripts to scan a single category
|
|
48324
|
+
* without instantiating all 99 rules. */
|
|
48325
|
+
removeWhere(predicate) {
|
|
48326
|
+
let removed = 0;
|
|
48327
|
+
for (const [id, rule] of this.rules) {
|
|
48328
|
+
if (predicate(rule)) {
|
|
48329
|
+
this.rules.delete(id);
|
|
48330
|
+
removed++;
|
|
48331
|
+
}
|
|
48332
|
+
}
|
|
48333
|
+
return removed;
|
|
48334
|
+
}
|
|
48335
|
+
all() {
|
|
48336
|
+
return Array.from(this.rules.values());
|
|
48337
|
+
}
|
|
47100
48338
|
createContexts(config, filePath, cwd, hotspotIssues = []) {
|
|
47101
48339
|
const context = {
|
|
47102
48340
|
config,
|
|
@@ -47122,1044 +48360,1943 @@ var signal_strength_default;
|
|
|
47122
48360
|
var init_signal_strength = __esm({
|
|
47123
48361
|
"src/rules/signal-strength.json"() {
|
|
47124
48362
|
signal_strength_default = {
|
|
47125
|
-
"
|
|
47126
|
-
recall:
|
|
47127
|
-
fpRate:
|
|
47128
|
-
ratio:
|
|
47129
|
-
precision: 0.
|
|
47130
|
-
lastCalibratedAt: "2026-
|
|
48363
|
+
"ai/any-density": {
|
|
48364
|
+
recall: 6e-3,
|
|
48365
|
+
fpRate: 37e-4,
|
|
48366
|
+
ratio: 175.31,
|
|
48367
|
+
precision: 0.6523,
|
|
48368
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
47131
48369
|
verdict: "USEFUL",
|
|
47132
|
-
_calibrationNote: "
|
|
47133
|
-
aiSpecific: true
|
|
48370
|
+
_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).",
|
|
48371
|
+
aiSpecific: true,
|
|
48372
|
+
_v7Verdict: "USEFUL",
|
|
48373
|
+
_v7Lift: 153.41,
|
|
48374
|
+
_v7Recall: 55e-4,
|
|
48375
|
+
_v7FpRate: 41e-4,
|
|
48376
|
+
_v7Precision: 0.634,
|
|
48377
|
+
_v8Verdict: "USEFUL",
|
|
48378
|
+
_v8Lift: 271.97
|
|
47134
48379
|
},
|
|
47135
|
-
"
|
|
47136
|
-
recall:
|
|
47137
|
-
fpRate:
|
|
47138
|
-
ratio:
|
|
47139
|
-
precision: 0.
|
|
47140
|
-
lastCalibratedAt: "2026-
|
|
47141
|
-
verdict: "
|
|
47142
|
-
_calibrationNote: "
|
|
47143
|
-
|
|
47144
|
-
|
|
48380
|
+
"ai/comment-ratio": {
|
|
48381
|
+
recall: 0.2771,
|
|
48382
|
+
fpRate: 0.1578,
|
|
48383
|
+
ratio: 4.26,
|
|
48384
|
+
precision: 0.6721,
|
|
48385
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
48386
|
+
verdict: "USEFUL",
|
|
48387
|
+
_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).",
|
|
48388
|
+
aiSpecific: true,
|
|
48389
|
+
_v7Verdict: "USEFUL",
|
|
48390
|
+
_v7Lift: 4.11,
|
|
48391
|
+
_v7Recall: 0.2545,
|
|
48392
|
+
_v7FpRate: 0.1629,
|
|
48393
|
+
_v7Precision: 0.6687,
|
|
48394
|
+
_v8Verdict: "USEFUL",
|
|
48395
|
+
_v8Lift: 4.73
|
|
47145
48396
|
},
|
|
47146
|
-
"
|
|
47147
|
-
recall: 0.
|
|
47148
|
-
fpRate: 0.
|
|
47149
|
-
ratio:
|
|
47150
|
-
precision: 0.
|
|
47151
|
-
lastCalibratedAt: "2026-
|
|
47152
|
-
verdict: "
|
|
47153
|
-
_calibrationNote: "
|
|
47154
|
-
aiSpecific:
|
|
48397
|
+
"ai/compression-profile": {
|
|
48398
|
+
recall: 0.3478,
|
|
48399
|
+
fpRate: 0.1488,
|
|
48400
|
+
ratio: 4.92,
|
|
48401
|
+
precision: 0.7318,
|
|
48402
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
48403
|
+
verdict: "USEFUL",
|
|
48404
|
+
_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).",
|
|
48405
|
+
aiSpecific: true,
|
|
48406
|
+
_v7Verdict: "USEFUL",
|
|
48407
|
+
_v7Lift: 4.89,
|
|
48408
|
+
_v7Recall: 0.3166,
|
|
48409
|
+
_v7FpRate: 0.1498,
|
|
48410
|
+
_v7Precision: 0.732,
|
|
48411
|
+
_v8Verdict: "USEFUL",
|
|
48412
|
+
_v8Lift: 5
|
|
47155
48413
|
},
|
|
47156
|
-
"
|
|
47157
|
-
recall:
|
|
48414
|
+
"ai/console-debug-storm": {
|
|
48415
|
+
recall: 73e-4,
|
|
47158
48416
|
fpRate: 9e-4,
|
|
47159
|
-
ratio:
|
|
47160
|
-
precision: 0.
|
|
47161
|
-
lastCalibratedAt: "2026-
|
|
48417
|
+
ratio: 949.21,
|
|
48418
|
+
precision: 0.9,
|
|
48419
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
47162
48420
|
verdict: "USEFUL",
|
|
47163
|
-
_calibrationNote: "
|
|
47164
|
-
aiSpecific: true
|
|
48421
|
+
_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).",
|
|
48422
|
+
aiSpecific: true,
|
|
48423
|
+
_v7Verdict: "USEFUL",
|
|
48424
|
+
_v7Lift: 960.19,
|
|
48425
|
+
_v7Recall: 81e-4,
|
|
48426
|
+
_v7FpRate: 1e-3,
|
|
48427
|
+
_v7Precision: 0.9161,
|
|
48428
|
+
_v8Verdict: "USEFUL",
|
|
48429
|
+
_v8Lift: 845.55
|
|
47165
48430
|
},
|
|
47166
|
-
"
|
|
47167
|
-
recall:
|
|
47168
|
-
fpRate:
|
|
47169
|
-
ratio:
|
|
47170
|
-
precision: 0.
|
|
47171
|
-
lastCalibratedAt: "2026-
|
|
48431
|
+
"ai/default-react-stack": {
|
|
48432
|
+
recall: 1e-3,
|
|
48433
|
+
fpRate: 0,
|
|
48434
|
+
ratio: 251225.49,
|
|
48435
|
+
precision: 0.9966,
|
|
48436
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
47172
48437
|
verdict: "USEFUL",
|
|
47173
|
-
_calibrationNote: "
|
|
47174
|
-
aiSpecific: true
|
|
48438
|
+
_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.",
|
|
48439
|
+
aiSpecific: true,
|
|
48440
|
+
_v7Verdict: "USEFUL",
|
|
48441
|
+
_v7Lift: 182622.43,
|
|
48442
|
+
_v7Recall: 1e-3,
|
|
48443
|
+
_v7FpRate: 0,
|
|
48444
|
+
_v7Precision: 0.9957,
|
|
48445
|
+
_v8Verdict: "USEFUL",
|
|
48446
|
+
_v8Lift: 99999,
|
|
48447
|
+
defaultOff: false
|
|
47175
48448
|
},
|
|
47176
|
-
"
|
|
47177
|
-
recall:
|
|
47178
|
-
fpRate: 0,
|
|
47179
|
-
ratio:
|
|
47180
|
-
precision: 0.
|
|
47181
|
-
lastCalibratedAt: "2026-
|
|
48449
|
+
"ai/errors-near-eof": {
|
|
48450
|
+
recall: 0.0948,
|
|
48451
|
+
fpRate: 0.052,
|
|
48452
|
+
ratio: 13.09,
|
|
48453
|
+
precision: 0.6803,
|
|
48454
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
47182
48455
|
verdict: "USEFUL",
|
|
47183
|
-
_calibrationNote: "
|
|
47184
|
-
aiSpecific: true
|
|
48456
|
+
_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).",
|
|
48457
|
+
aiSpecific: true,
|
|
48458
|
+
_v7Verdict: "USEFUL",
|
|
48459
|
+
_v7Lift: 11.29,
|
|
48460
|
+
_v7Recall: 0.0704,
|
|
48461
|
+
_v7FpRate: 0.0551,
|
|
48462
|
+
_v7Precision: 0.6225,
|
|
48463
|
+
_v8Verdict: "USEFUL",
|
|
48464
|
+
_v8Lift: 18.16
|
|
47185
48465
|
},
|
|
47186
|
-
"
|
|
47187
|
-
recall:
|
|
48466
|
+
"ai/fetch-default-overuse": {
|
|
48467
|
+
recall: 27e-4,
|
|
47188
48468
|
fpRate: 3e-4,
|
|
47189
|
-
ratio:
|
|
47190
|
-
precision: 0.
|
|
47191
|
-
lastCalibratedAt: "2026-
|
|
48469
|
+
ratio: 2679.84,
|
|
48470
|
+
precision: 0.9036,
|
|
48471
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
47192
48472
|
verdict: "USEFUL",
|
|
47193
|
-
_calibrationNote: "
|
|
47194
|
-
aiSpecific: true
|
|
48473
|
+
_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).",
|
|
48474
|
+
aiSpecific: true,
|
|
48475
|
+
_v7Verdict: "USEFUL",
|
|
48476
|
+
_v7Lift: 2166.14,
|
|
48477
|
+
_v7Recall: 28e-4,
|
|
48478
|
+
_v7FpRate: 4e-4,
|
|
48479
|
+
_v7Precision: 0.8976,
|
|
48480
|
+
_v8Verdict: "USEFUL",
|
|
48481
|
+
_v8Lift: 7139.19
|
|
47195
48482
|
},
|
|
47196
|
-
"
|
|
47197
|
-
recall:
|
|
48483
|
+
"ai/library-reinvention": {
|
|
48484
|
+
recall: 3e-4,
|
|
47198
48485
|
fpRate: 0,
|
|
47199
|
-
ratio:
|
|
47200
|
-
precision: 0.
|
|
47201
|
-
lastCalibratedAt: "2026-
|
|
47202
|
-
verdict: "USEFUL",
|
|
47203
|
-
_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.",
|
|
47204
|
-
aiSpecific: true
|
|
47205
|
-
},
|
|
47206
|
-
"visual/math-default-font": {
|
|
47207
|
-
recall: 13e-4,
|
|
47208
|
-
fpRate: 4e-4,
|
|
47209
|
-
ratio: 3.4,
|
|
47210
|
-
precision: 0.8151,
|
|
47211
|
-
lastCalibratedAt: "2026-06-27T12:00:00Z",
|
|
48486
|
+
ratio: 47415.05,
|
|
48487
|
+
precision: 0.9405,
|
|
48488
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
47212
48489
|
verdict: "USEFUL",
|
|
47213
|
-
_calibrationNote: "
|
|
47214
|
-
aiSpecific: true
|
|
48490
|
+
_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).",
|
|
48491
|
+
aiSpecific: true,
|
|
48492
|
+
_v7Verdict: "USEFUL",
|
|
48493
|
+
_v7Lift: 34024.44,
|
|
48494
|
+
_v7Recall: 3e-4,
|
|
48495
|
+
_v7FpRate: 0,
|
|
48496
|
+
_v7Precision: 0.9275,
|
|
48497
|
+
_v8Verdict: "USEFUL",
|
|
48498
|
+
_v8Lift: 99999
|
|
47215
48499
|
},
|
|
47216
|
-
"
|
|
48500
|
+
"ai/log-rank-histogram": {
|
|
47217
48501
|
recall: 0,
|
|
47218
48502
|
fpRate: 0,
|
|
47219
48503
|
ratio: 0,
|
|
47220
48504
|
precision: 0,
|
|
47221
|
-
lastCalibratedAt: "2026-
|
|
48505
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
47222
48506
|
verdict: "DORMANT",
|
|
47223
|
-
|
|
47224
|
-
|
|
47225
|
-
|
|
48507
|
+
_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.",
|
|
48508
|
+
aiSpecific: true,
|
|
48509
|
+
_v7Verdict: "OK",
|
|
48510
|
+
_v7Lift: 0,
|
|
48511
|
+
_v7Recall: 0,
|
|
48512
|
+
_v7FpRate: 0,
|
|
48513
|
+
_v7Precision: 0,
|
|
48514
|
+
_v8Verdict: "DORMANT",
|
|
48515
|
+
_v8Lift: 1,
|
|
48516
|
+
defaultOff: true
|
|
47226
48517
|
},
|
|
47227
|
-
"
|
|
47228
|
-
recall:
|
|
47229
|
-
fpRate:
|
|
47230
|
-
ratio:
|
|
47231
|
-
precision: 0.
|
|
47232
|
-
lastCalibratedAt: "2026-
|
|
47233
|
-
verdict: "
|
|
47234
|
-
_calibrationNote: "
|
|
47235
|
-
aiSpecific: true
|
|
48518
|
+
"ai/markdown-leakage": {
|
|
48519
|
+
recall: 0,
|
|
48520
|
+
fpRate: 0,
|
|
48521
|
+
ratio: 10003.17,
|
|
48522
|
+
precision: 0.3571,
|
|
48523
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
48524
|
+
verdict: "OK",
|
|
48525
|
+
_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).",
|
|
48526
|
+
aiSpecific: true,
|
|
48527
|
+
_v7Verdict: "USEFUL",
|
|
48528
|
+
_v7Lift: 65504.64,
|
|
48529
|
+
_v7Recall: 0,
|
|
48530
|
+
_v7FpRate: 0,
|
|
48531
|
+
_v7Precision: 0.7143,
|
|
48532
|
+
_v8Verdict: "INVERTED",
|
|
48533
|
+
_v8Lift: 0
|
|
47236
48534
|
},
|
|
47237
|
-
"
|
|
47238
|
-
recall:
|
|
47239
|
-
fpRate:
|
|
47240
|
-
ratio:
|
|
47241
|
-
precision: 0.
|
|
47242
|
-
lastCalibratedAt: "2026-
|
|
48535
|
+
"ai/renyi-profile": {
|
|
48536
|
+
recall: 0,
|
|
48537
|
+
fpRate: 0,
|
|
48538
|
+
ratio: 5251.67,
|
|
48539
|
+
precision: 0.25,
|
|
48540
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
48541
|
+
verdict: "OK",
|
|
48542
|
+
_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).",
|
|
48543
|
+
aiSpecific: true,
|
|
48544
|
+
_v7Verdict: "OK",
|
|
48545
|
+
_v7Lift: 5094.81,
|
|
48546
|
+
_v7Recall: 0,
|
|
48547
|
+
_v7FpRate: 0,
|
|
48548
|
+
_v7Precision: 0.25,
|
|
48549
|
+
_v8Verdict: "OK",
|
|
48550
|
+
_v8Lift: 5722.25
|
|
48551
|
+
},
|
|
48552
|
+
"ai/segment-surprisal-cv": {
|
|
48553
|
+
recall: 0.2019,
|
|
48554
|
+
fpRate: 0.0787,
|
|
48555
|
+
ratio: 9.52,
|
|
48556
|
+
precision: 0.7495,
|
|
48557
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
47243
48558
|
verdict: "USEFUL",
|
|
47244
|
-
_calibrationNote: "
|
|
47245
|
-
aiSpecific: true
|
|
48559
|
+
_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).",
|
|
48560
|
+
aiSpecific: true,
|
|
48561
|
+
_v7Verdict: "USEFUL",
|
|
48562
|
+
_v7Lift: 9.11,
|
|
48563
|
+
_v7Recall: 0.1836,
|
|
48564
|
+
_v7FpRate: 0.0817,
|
|
48565
|
+
_v7Precision: 0.7438,
|
|
48566
|
+
_v8Verdict: "USEFUL",
|
|
48567
|
+
_v8Lift: 10.8
|
|
47246
48568
|
},
|
|
47247
|
-
"
|
|
47248
|
-
recall:
|
|
48569
|
+
"ai/state-default-overuse": {
|
|
48570
|
+
recall: 3e-3,
|
|
47249
48571
|
fpRate: 6e-4,
|
|
47250
|
-
ratio:
|
|
47251
|
-
precision: 0.
|
|
47252
|
-
lastCalibratedAt: "2026-
|
|
48572
|
+
ratio: 1315.06,
|
|
48573
|
+
precision: 0.8451,
|
|
48574
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
47253
48575
|
verdict: "USEFUL",
|
|
47254
|
-
_calibrationNote: "
|
|
47255
|
-
aiSpecific: true
|
|
48576
|
+
_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).",
|
|
48577
|
+
aiSpecific: true,
|
|
48578
|
+
_v7Verdict: "USEFUL",
|
|
48579
|
+
_v7Lift: 947.32,
|
|
48580
|
+
_v7Recall: 3e-3,
|
|
48581
|
+
_v7FpRate: 9e-4,
|
|
48582
|
+
_v7Precision: 0.8161,
|
|
48583
|
+
_v8Verdict: "USEFUL",
|
|
48584
|
+
_v8Lift: 16799.55
|
|
47256
48585
|
},
|
|
47257
|
-
"
|
|
48586
|
+
"ai/tailwind-color-overuse": {
|
|
48587
|
+
recall: 0.0264,
|
|
48588
|
+
fpRate: 38e-4,
|
|
48589
|
+
ratio: 230.97,
|
|
48590
|
+
precision: 0.8888,
|
|
48591
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
48592
|
+
verdict: "USEFUL",
|
|
48593
|
+
_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).",
|
|
48594
|
+
aiSpecific: true,
|
|
48595
|
+
_v7Verdict: "USEFUL",
|
|
48596
|
+
_v7Lift: 161.52,
|
|
48597
|
+
_v7Recall: 0.0218,
|
|
48598
|
+
_v7FpRate: 52e-4,
|
|
48599
|
+
_v7Precision: 0.8436,
|
|
48600
|
+
_v8Verdict: "USEFUL",
|
|
48601
|
+
_v8Lift: 5695.79
|
|
48602
|
+
},
|
|
48603
|
+
"ai/text-like-ratio": {
|
|
48604
|
+
recall: 0,
|
|
48605
|
+
fpRate: 0,
|
|
48606
|
+
ratio: 201664,
|
|
48607
|
+
precision: 0.8,
|
|
48608
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
48609
|
+
verdict: "USEFUL",
|
|
48610
|
+
_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).",
|
|
48611
|
+
aiSpecific: true,
|
|
48612
|
+
_v7Verdict: "USEFUL",
|
|
48613
|
+
_v7Lift: 137559.75,
|
|
48614
|
+
_v7Recall: 0,
|
|
48615
|
+
_v7FpRate: 0,
|
|
48616
|
+
_v7Precision: 0.75,
|
|
48617
|
+
_v8Verdict: "USEFUL",
|
|
48618
|
+
_v8Lift: 99999
|
|
48619
|
+
},
|
|
48620
|
+
"ai/whitespace-regularity": {
|
|
48621
|
+
recall: 0.0733,
|
|
48622
|
+
fpRate: 0.0677,
|
|
48623
|
+
ratio: 8.25,
|
|
48624
|
+
precision: 0.5583,
|
|
48625
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
48626
|
+
verdict: "USEFUL",
|
|
48627
|
+
_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).",
|
|
48628
|
+
aiSpecific: true,
|
|
48629
|
+
_v7Verdict: "USEFUL",
|
|
48630
|
+
_v7Lift: 7.71,
|
|
48631
|
+
_v7Recall: 0.0737,
|
|
48632
|
+
_v7FpRate: 0.0733,
|
|
48633
|
+
_v7Precision: 0.5652,
|
|
48634
|
+
_v8Verdict: "USEFUL",
|
|
48635
|
+
_v8Lift: 10.06
|
|
48636
|
+
},
|
|
48637
|
+
"arch/astro-island-leak": {
|
|
47258
48638
|
recall: 0,
|
|
47259
48639
|
fpRate: 0,
|
|
47260
48640
|
ratio: 0,
|
|
47261
48641
|
precision: 0,
|
|
47262
|
-
lastCalibratedAt: "2026-
|
|
48642
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
47263
48643
|
verdict: "DORMANT",
|
|
47264
|
-
|
|
47265
|
-
|
|
47266
|
-
|
|
48644
|
+
_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.",
|
|
48645
|
+
aiSpecific: true,
|
|
48646
|
+
_v7Verdict: "DORMANT",
|
|
48647
|
+
_v7Lift: 0,
|
|
48648
|
+
_v7Recall: 0,
|
|
48649
|
+
_v7FpRate: 0,
|
|
48650
|
+
_v7Precision: 0,
|
|
48651
|
+
_v8Verdict: "DORMANT",
|
|
48652
|
+
_v8Lift: 1,
|
|
48653
|
+
defaultOff: true
|
|
47267
48654
|
},
|
|
47268
48655
|
"component/giant-component": {
|
|
47269
|
-
recall: 0.
|
|
47270
|
-
fpRate:
|
|
47271
|
-
ratio:
|
|
47272
|
-
precision: 0.
|
|
47273
|
-
lastCalibratedAt: "2026-
|
|
48656
|
+
recall: 0.0181,
|
|
48657
|
+
fpRate: 59e-4,
|
|
48658
|
+
ratio: 132.31,
|
|
48659
|
+
precision: 0.7815,
|
|
48660
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
47274
48661
|
verdict: "USEFUL",
|
|
47275
|
-
_calibrationNote: "
|
|
47276
|
-
aiSpecific: true
|
|
48662
|
+
_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).",
|
|
48663
|
+
aiSpecific: true,
|
|
48664
|
+
_v7Verdict: "USEFUL",
|
|
48665
|
+
_v7Lift: 97.16,
|
|
48666
|
+
_v7Recall: 0.0177,
|
|
48667
|
+
_v7FpRate: 77e-4,
|
|
48668
|
+
_v7Precision: 0.7485,
|
|
48669
|
+
_v8Verdict: "USEFUL",
|
|
48670
|
+
_v8Lift: 846.15
|
|
48671
|
+
},
|
|
48672
|
+
"component/multiple-components-per-file": {
|
|
48673
|
+
recall: 0.0751,
|
|
48674
|
+
fpRate: 0.0423,
|
|
48675
|
+
ratio: 15.96,
|
|
48676
|
+
precision: 0.6747,
|
|
48677
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
48678
|
+
verdict: "USEFUL",
|
|
48679
|
+
_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).",
|
|
48680
|
+
aiSpecific: false,
|
|
48681
|
+
_v7Verdict: "USEFUL",
|
|
48682
|
+
_v7Lift: 12.04,
|
|
48683
|
+
_v7Recall: 0.0687,
|
|
48684
|
+
_v7FpRate: 0.0523,
|
|
48685
|
+
_v7Precision: 0.6294,
|
|
48686
|
+
_v8Verdict: "USEFUL",
|
|
48687
|
+
_v8Lift: 54.44
|
|
47277
48688
|
},
|
|
47278
48689
|
"component/shadcn-prop-mismatch": {
|
|
47279
|
-
recall:
|
|
48690
|
+
recall: 16e-4,
|
|
47280
48691
|
fpRate: 1e-4,
|
|
47281
|
-
ratio:
|
|
47282
|
-
precision: 0.
|
|
47283
|
-
lastCalibratedAt: "2026-
|
|
48692
|
+
ratio: 9990.98,
|
|
48693
|
+
precision: 0.9512,
|
|
48694
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
47284
48695
|
verdict: "USEFUL",
|
|
47285
|
-
_calibrationNote: "
|
|
47286
|
-
aiSpecific: true
|
|
48696
|
+
_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.",
|
|
48697
|
+
aiSpecific: true,
|
|
48698
|
+
_v7Verdict: "USEFUL",
|
|
48699
|
+
_v7Lift: 7099.57,
|
|
48700
|
+
_v7Recall: 13e-4,
|
|
48701
|
+
_v7FpRate: 1e-4,
|
|
48702
|
+
_v7Precision: 0.929,
|
|
48703
|
+
_v8Verdict: "USEFUL",
|
|
48704
|
+
_v8Lift: 99999,
|
|
48705
|
+
defaultOff: false
|
|
47287
48706
|
},
|
|
47288
|
-
"
|
|
47289
|
-
recall:
|
|
47290
|
-
fpRate:
|
|
47291
|
-
ratio:
|
|
47292
|
-
precision: 0.
|
|
47293
|
-
lastCalibratedAt: "2026-
|
|
47294
|
-
verdict: "OK",
|
|
47295
|
-
_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.",
|
|
47296
|
-
aiSpecific: true
|
|
47297
|
-
},
|
|
47298
|
-
"layout/math-element-uniformity": {
|
|
47299
|
-
recall: 28e-4,
|
|
47300
|
-
fpRate: 12e-4,
|
|
47301
|
-
ratio: 2.28,
|
|
47302
|
-
precision: 0.7475,
|
|
47303
|
-
lastCalibratedAt: "2026-06-27T12:00:00Z",
|
|
48707
|
+
"context/import-path-mismatch": {
|
|
48708
|
+
recall: 0.0681,
|
|
48709
|
+
fpRate: 0.0167,
|
|
48710
|
+
ratio: 49.48,
|
|
48711
|
+
precision: 0.8263,
|
|
48712
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
47304
48713
|
verdict: "USEFUL",
|
|
47305
|
-
_calibrationNote: "
|
|
47306
|
-
aiSpecific:
|
|
48714
|
+
_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).",
|
|
48715
|
+
aiSpecific: false,
|
|
48716
|
+
_v7Verdict: "USEFUL",
|
|
48717
|
+
_v7Lift: 35.26,
|
|
48718
|
+
_v7Recall: 0.0746,
|
|
48719
|
+
_v7FpRate: 0.0229,
|
|
48720
|
+
_v7Precision: 0.8079,
|
|
48721
|
+
_v8Verdict: "USEFUL",
|
|
48722
|
+
_v8Lift: 8554.38
|
|
47307
48723
|
},
|
|
47308
|
-
"
|
|
47309
|
-
recall: 2e-4,
|
|
47310
|
-
fpRate: 1e-4,
|
|
47311
|
-
ratio: 1.36,
|
|
47312
|
-
precision: 0.6379,
|
|
47313
|
-
lastCalibratedAt: "2026-06-27T12:00:00Z",
|
|
47314
|
-
verdict: "HYGIENE",
|
|
47315
|
-
_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.",
|
|
47316
|
-
aiSpecific: false
|
|
47317
|
-
},
|
|
47318
|
-
"perf/css-bloat": {
|
|
47319
|
-
recall: 0.0117,
|
|
47320
|
-
fpRate: 32e-4,
|
|
47321
|
-
ratio: 3.64,
|
|
47322
|
-
precision: 0.8252,
|
|
47323
|
-
lastCalibratedAt: "2026-06-27T12:00:00Z",
|
|
47324
|
-
verdict: "HYGIENE",
|
|
47325
|
-
_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.",
|
|
47326
|
-
aiSpecific: false
|
|
47327
|
-
},
|
|
47328
|
-
"wcag/focus-appearance": {
|
|
47329
|
-
recall: 26e-4,
|
|
47330
|
-
fpRate: 1e-4,
|
|
47331
|
-
ratio: 19.68,
|
|
47332
|
-
precision: 0.9623,
|
|
47333
|
-
lastCalibratedAt: "2026-06-27T12:00:00Z",
|
|
47334
|
-
verdict: "HYGIENE",
|
|
47335
|
-
_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.",
|
|
47336
|
-
aiSpecific: false
|
|
47337
|
-
},
|
|
47338
|
-
"wcag/target-size": {
|
|
48724
|
+
"db/duplicate-index": {
|
|
47339
48725
|
recall: 0,
|
|
47340
48726
|
fpRate: 0,
|
|
47341
48727
|
ratio: 0,
|
|
47342
48728
|
precision: 0,
|
|
47343
|
-
lastCalibratedAt: "2026-
|
|
48729
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
47344
48730
|
verdict: "DORMANT",
|
|
47345
|
-
|
|
47346
|
-
|
|
47347
|
-
|
|
47348
|
-
|
|
47349
|
-
|
|
47350
|
-
|
|
47351
|
-
|
|
47352
|
-
|
|
47353
|
-
|
|
47354
|
-
|
|
47355
|
-
verdict: "HYGIENE",
|
|
47356
|
-
_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.",
|
|
47357
|
-
aiSpecific: false
|
|
47358
|
-
},
|
|
47359
|
-
"context/import-path-mismatch": {
|
|
47360
|
-
recall: 0.0739,
|
|
47361
|
-
fpRate: 0.0228,
|
|
47362
|
-
ratio: 3.25,
|
|
47363
|
-
precision: 0.8079,
|
|
47364
|
-
lastCalibratedAt: "2026-06-27T12:00:00Z",
|
|
47365
|
-
verdict: "HYGIENE",
|
|
47366
|
-
_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.",
|
|
47367
|
-
aiSpecific: false
|
|
47368
|
-
},
|
|
47369
|
-
"logic/key-prop-missing": {
|
|
47370
|
-
recall: 17e-4,
|
|
47371
|
-
fpRate: 14e-4,
|
|
47372
|
-
ratio: 1.28,
|
|
47373
|
-
precision: 0.6246,
|
|
47374
|
-
lastCalibratedAt: "2026-06-27T12:00:00Z",
|
|
47375
|
-
verdict: "HYGIENE",
|
|
47376
|
-
_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.",
|
|
47377
|
-
aiSpecific: false
|
|
47378
|
-
},
|
|
47379
|
-
"logic/math-variable-name-entropy": {
|
|
47380
|
-
recall: 2e-4,
|
|
47381
|
-
fpRate: 1e-4,
|
|
47382
|
-
ratio: 1.07,
|
|
47383
|
-
precision: 0.5806,
|
|
47384
|
-
lastCalibratedAt: "2026-06-27T12:00:00Z",
|
|
47385
|
-
verdict: "HYGIENE",
|
|
47386
|
-
_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.",
|
|
47387
|
-
aiSpecific: false
|
|
47388
|
-
},
|
|
47389
|
-
"security/public-admin-route": {
|
|
47390
|
-
recall: 28e-4,
|
|
47391
|
-
fpRate: 78e-4,
|
|
47392
|
-
ratio: 0.4,
|
|
47393
|
-
precision: 0.2251,
|
|
47394
|
-
lastCalibratedAt: "2026-06-26T22:30:00Z",
|
|
47395
|
-
verdict: "HYGIENE",
|
|
47396
|
-
_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]",
|
|
47397
|
-
defaultOff: true,
|
|
47398
|
-
aiSpecific: false
|
|
47399
|
-
},
|
|
47400
|
-
"security/unsafe-html-render": {
|
|
47401
|
-
recall: 13e-4,
|
|
47402
|
-
fpRate: 9e-4,
|
|
47403
|
-
ratio: 1.5,
|
|
47404
|
-
precision: 0.661,
|
|
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=312, FP=160, P=66.1%, FPR=0.09%, lift=1.5. aiSpecific=False.",
|
|
47408
|
-
aiSpecific: false
|
|
47409
|
-
},
|
|
47410
|
-
"visual/naturalness-anomaly": {
|
|
47411
|
-
recall: 0.1645,
|
|
47412
|
-
fpRate: 0.0617,
|
|
47413
|
-
ratio: 2.67,
|
|
47414
|
-
precision: 0.7755,
|
|
47415
|
-
lastCalibratedAt: "2026-06-27T12:00:00Z",
|
|
47416
|
-
verdict: "USEFUL",
|
|
47417
|
-
_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.",
|
|
47418
|
-
aiSpecific: true
|
|
48731
|
+
_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.",
|
|
48732
|
+
aiSpecific: false,
|
|
48733
|
+
_v7Verdict: "DORMANT",
|
|
48734
|
+
_v7Lift: 0,
|
|
48735
|
+
_v7Recall: 0,
|
|
48736
|
+
_v7FpRate: 0,
|
|
48737
|
+
_v7Precision: 0,
|
|
48738
|
+
_v8Verdict: "DORMANT",
|
|
48739
|
+
_v8Lift: 1,
|
|
48740
|
+
defaultOff: true
|
|
47419
48741
|
},
|
|
47420
|
-
"
|
|
48742
|
+
"db/enum-sprawl": {
|
|
47421
48743
|
recall: 0,
|
|
47422
48744
|
fpRate: 0,
|
|
47423
|
-
ratio:
|
|
47424
|
-
precision: 0
|
|
47425
|
-
lastCalibratedAt: "2026-
|
|
47426
|
-
verdict: "
|
|
47427
|
-
_calibrationNote: "
|
|
47428
|
-
aiSpecific:
|
|
48745
|
+
ratio: 0,
|
|
48746
|
+
precision: 0,
|
|
48747
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
48748
|
+
verdict: "DORMANT",
|
|
48749
|
+
_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.",
|
|
48750
|
+
aiSpecific: false,
|
|
48751
|
+
_v7Verdict: "DORMANT",
|
|
48752
|
+
_v7Lift: 0,
|
|
48753
|
+
_v7Recall: 0,
|
|
48754
|
+
_v7FpRate: 0,
|
|
48755
|
+
_v7Precision: 0,
|
|
48756
|
+
_v8Verdict: "DORMANT",
|
|
48757
|
+
_v8Lift: 1,
|
|
48758
|
+
defaultOff: true
|
|
47429
48759
|
},
|
|
47430
|
-
"
|
|
48760
|
+
"db/missing-fk-index": {
|
|
47431
48761
|
recall: 0,
|
|
47432
48762
|
fpRate: 0,
|
|
47433
48763
|
ratio: 0,
|
|
47434
48764
|
precision: 0,
|
|
47435
|
-
lastCalibratedAt: "2026-
|
|
48765
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
47436
48766
|
verdict: "DORMANT",
|
|
47437
|
-
|
|
47438
|
-
|
|
47439
|
-
|
|
48767
|
+
_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.",
|
|
48768
|
+
aiSpecific: false,
|
|
48769
|
+
_v7Verdict: "DORMANT",
|
|
48770
|
+
_v7Lift: 0,
|
|
48771
|
+
_v7Recall: 0,
|
|
48772
|
+
_v7FpRate: 0,
|
|
48773
|
+
_v7Precision: 0,
|
|
48774
|
+
_v8Verdict: "DORMANT",
|
|
48775
|
+
_v8Lift: 1,
|
|
48776
|
+
defaultOff: true
|
|
47440
48777
|
},
|
|
47441
|
-
"
|
|
48778
|
+
"db/missing-not-null": {
|
|
47442
48779
|
recall: 0,
|
|
47443
48780
|
fpRate: 0,
|
|
47444
48781
|
ratio: 0,
|
|
47445
48782
|
precision: 0,
|
|
47446
|
-
lastCalibratedAt: "2026-
|
|
48783
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
47447
48784
|
verdict: "DORMANT",
|
|
47448
|
-
|
|
47449
|
-
|
|
47450
|
-
|
|
48785
|
+
_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.",
|
|
48786
|
+
aiSpecific: false,
|
|
48787
|
+
_v7Verdict: "DORMANT",
|
|
48788
|
+
_v7Lift: 0,
|
|
48789
|
+
_v7Recall: 0,
|
|
48790
|
+
_v7FpRate: 0,
|
|
48791
|
+
_v7Precision: 0,
|
|
48792
|
+
_v8Verdict: "DORMANT",
|
|
48793
|
+
_v8Lift: 1,
|
|
48794
|
+
defaultOff: true
|
|
47451
48795
|
},
|
|
47452
|
-
"
|
|
48796
|
+
"db/naming-inconsistency": {
|
|
47453
48797
|
recall: 0,
|
|
47454
48798
|
fpRate: 0,
|
|
47455
48799
|
ratio: 0,
|
|
47456
48800
|
precision: 0,
|
|
47457
|
-
lastCalibratedAt: "2026-
|
|
48801
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
47458
48802
|
verdict: "DORMANT",
|
|
47459
|
-
|
|
47460
|
-
|
|
47461
|
-
|
|
48803
|
+
_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.",
|
|
48804
|
+
aiSpecific: false,
|
|
48805
|
+
_v7Verdict: "DORMANT",
|
|
48806
|
+
_v7Lift: 0,
|
|
48807
|
+
_v7Recall: 0,
|
|
48808
|
+
_v7FpRate: 0,
|
|
48809
|
+
_v7Precision: 0,
|
|
48810
|
+
_v8Verdict: "DORMANT",
|
|
48811
|
+
_v8Lift: 1,
|
|
48812
|
+
defaultOff: true
|
|
47462
48813
|
},
|
|
47463
|
-
"
|
|
48814
|
+
"db/sql-concat": {
|
|
48815
|
+
recall: 5e-4,
|
|
48816
|
+
fpRate: 1e-4,
|
|
48817
|
+
ratio: 7511.26,
|
|
48818
|
+
precision: 0.8343,
|
|
48819
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
48820
|
+
verdict: "USEFUL",
|
|
48821
|
+
_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).",
|
|
48822
|
+
aiSpecific: true,
|
|
48823
|
+
_v7Verdict: "DORMANT",
|
|
48824
|
+
_v7Lift: 1,
|
|
48825
|
+
_v7Recall: 0,
|
|
48826
|
+
_v7FpRate: 0,
|
|
48827
|
+
_v7Precision: 0,
|
|
48828
|
+
_v8Verdict: "USEFUL",
|
|
48829
|
+
_v8Lift: 2046.08
|
|
48830
|
+
},
|
|
48831
|
+
"dead/dead-branch": {
|
|
48832
|
+
recall: 2e-4,
|
|
48833
|
+
fpRate: 4e-4,
|
|
48834
|
+
ratio: 1080.68,
|
|
48835
|
+
precision: 0.4244,
|
|
48836
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
48837
|
+
verdict: "OK",
|
|
48838
|
+
_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.",
|
|
48839
|
+
aiSpecific: true,
|
|
48840
|
+
_v7Verdict: "DORMANT",
|
|
48841
|
+
_v7Lift: 1,
|
|
48842
|
+
_v7Recall: 0,
|
|
48843
|
+
_v7FpRate: 0,
|
|
48844
|
+
_v7Precision: 0,
|
|
48845
|
+
_v8Verdict: "OK",
|
|
48846
|
+
_v8Lift: 294.38
|
|
48847
|
+
},
|
|
48848
|
+
"dead/unreachable": {
|
|
48849
|
+
recall: 1e-4,
|
|
48850
|
+
fpRate: 6e-4,
|
|
48851
|
+
ratio: 153.14,
|
|
48852
|
+
precision: 0.0966,
|
|
48853
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
48854
|
+
verdict: "OK",
|
|
48855
|
+
_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.",
|
|
48856
|
+
aiSpecific: true,
|
|
48857
|
+
_v7Verdict: "DORMANT",
|
|
48858
|
+
_v7Lift: 1,
|
|
48859
|
+
_v7Recall: 0,
|
|
48860
|
+
_v7FpRate: 0,
|
|
48861
|
+
_v7Precision: 0,
|
|
48862
|
+
_v8Verdict: "OK",
|
|
48863
|
+
_v8Lift: 41.71
|
|
48864
|
+
},
|
|
48865
|
+
"dead/unused-import": {
|
|
48866
|
+
recall: 0.0379,
|
|
48867
|
+
fpRate: 0.0222,
|
|
48868
|
+
ratio: 30.06,
|
|
48869
|
+
precision: 0.6662,
|
|
48870
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
48871
|
+
verdict: "USEFUL",
|
|
48872
|
+
_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.",
|
|
48873
|
+
aiSpecific: true,
|
|
48874
|
+
_v7Verdict: "DORMANT",
|
|
48875
|
+
_v7Lift: 1,
|
|
48876
|
+
_v7Recall: 0,
|
|
48877
|
+
_v7FpRate: 0,
|
|
48878
|
+
_v7Precision: 0,
|
|
48879
|
+
_v8Verdict: "USEFUL",
|
|
48880
|
+
_v8Lift: 8.19
|
|
48881
|
+
},
|
|
48882
|
+
"dead/unused-local": {
|
|
48883
|
+
recall: 0.0477,
|
|
48884
|
+
fpRate: 74e-4,
|
|
48885
|
+
ratio: 120.18,
|
|
48886
|
+
precision: 0.8834,
|
|
48887
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
48888
|
+
verdict: "USEFUL",
|
|
48889
|
+
_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.",
|
|
48890
|
+
aiSpecific: true,
|
|
48891
|
+
_v7Verdict: "DORMANT",
|
|
48892
|
+
_v7Lift: 1,
|
|
48893
|
+
_v7Recall: 0,
|
|
48894
|
+
_v7FpRate: 0,
|
|
48895
|
+
_v7Precision: 0,
|
|
48896
|
+
_v8Verdict: "USEFUL",
|
|
48897
|
+
_v8Lift: 32.74,
|
|
48898
|
+
defaultOff: false
|
|
48899
|
+
},
|
|
48900
|
+
"dead/unused-parameter": {
|
|
48901
|
+
recall: 8e-4,
|
|
48902
|
+
fpRate: 27e-4,
|
|
48903
|
+
ratio: 98,
|
|
48904
|
+
precision: 0.2628,
|
|
48905
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
48906
|
+
verdict: "OK",
|
|
48907
|
+
_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.",
|
|
48908
|
+
aiSpecific: true,
|
|
48909
|
+
_v7Verdict: "DORMANT",
|
|
48910
|
+
_v7Lift: 1,
|
|
48911
|
+
_v7Recall: 0,
|
|
48912
|
+
_v7FpRate: 0,
|
|
48913
|
+
_v7Precision: 0,
|
|
48914
|
+
_v8Verdict: "OK",
|
|
48915
|
+
_v8Lift: 26.7
|
|
48916
|
+
},
|
|
48917
|
+
"docs/broken-link": {
|
|
48918
|
+
recall: 14e-4,
|
|
48919
|
+
fpRate: 23e-4,
|
|
48920
|
+
ratio: 178.13,
|
|
48921
|
+
precision: 0.4155,
|
|
48922
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
48923
|
+
verdict: "OK",
|
|
48924
|
+
_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).",
|
|
48925
|
+
aiSpecific: false,
|
|
48926
|
+
_v7Verdict: "DORMANT",
|
|
48927
|
+
_v7Lift: 1,
|
|
48928
|
+
_v7Recall: 0,
|
|
48929
|
+
_v7FpRate: 0,
|
|
48930
|
+
_v7Precision: 0,
|
|
48931
|
+
_v8Verdict: "OK",
|
|
48932
|
+
_v8Lift: 48.52
|
|
48933
|
+
},
|
|
48934
|
+
"docs/expired-code-example": {
|
|
47464
48935
|
recall: 0,
|
|
47465
48936
|
fpRate: 0,
|
|
47466
48937
|
ratio: 0,
|
|
47467
48938
|
precision: 0,
|
|
47468
|
-
lastCalibratedAt: "2026-
|
|
48939
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
48940
|
+
verdict: "INVERTED",
|
|
48941
|
+
_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).",
|
|
48942
|
+
aiSpecific: false,
|
|
48943
|
+
_v7Verdict: "DORMANT",
|
|
48944
|
+
_v7Lift: 1,
|
|
48945
|
+
_v7Recall: 0,
|
|
48946
|
+
_v7FpRate: 0,
|
|
48947
|
+
_v7Precision: 0,
|
|
48948
|
+
_v8Verdict: "INVERTED",
|
|
48949
|
+
_v8Lift: 0,
|
|
48950
|
+
defaultOff: true
|
|
48951
|
+
},
|
|
48952
|
+
"docs/stale-function-reference": {
|
|
48953
|
+
recall: 26e-4,
|
|
48954
|
+
fpRate: 5e-4,
|
|
48955
|
+
ratio: 1638.47,
|
|
48956
|
+
precision: 0.8515,
|
|
48957
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
48958
|
+
verdict: "USEFUL",
|
|
48959
|
+
_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).",
|
|
48960
|
+
aiSpecific: false,
|
|
48961
|
+
_v7Verdict: "DORMANT",
|
|
48962
|
+
_v7Lift: 1,
|
|
48963
|
+
_v7Recall: 0,
|
|
48964
|
+
_v7FpRate: 0,
|
|
48965
|
+
_v7Precision: 0,
|
|
48966
|
+
_v8Verdict: "USEFUL",
|
|
48967
|
+
_v8Lift: 446.32
|
|
48968
|
+
},
|
|
48969
|
+
"docs/stale-package-reference": {
|
|
48970
|
+
recall: 2e-4,
|
|
48971
|
+
fpRate: 4e-4,
|
|
48972
|
+
ratio: 939.43,
|
|
48973
|
+
precision: 0.3429,
|
|
48974
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
48975
|
+
verdict: "OK",
|
|
48976
|
+
_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).",
|
|
48977
|
+
aiSpecific: false,
|
|
48978
|
+
_v7Verdict: "DORMANT",
|
|
48979
|
+
_v7Lift: 1,
|
|
48980
|
+
_v7Recall: 0,
|
|
48981
|
+
_v7FpRate: 0,
|
|
48982
|
+
_v7Precision: 0,
|
|
48983
|
+
_v8Verdict: "OK",
|
|
48984
|
+
_v8Lift: 255.9
|
|
48985
|
+
},
|
|
48986
|
+
"dup/identical-block": {
|
|
48987
|
+
recall: 0,
|
|
48988
|
+
fpRate: 0,
|
|
48989
|
+
ratio: 1,
|
|
48990
|
+
precision: 0,
|
|
48991
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
47469
48992
|
verdict: "DORMANT",
|
|
47470
|
-
|
|
47471
|
-
|
|
47472
|
-
|
|
48993
|
+
_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.",
|
|
48994
|
+
aiSpecific: false,
|
|
48995
|
+
_v7Verdict: "DORMANT",
|
|
48996
|
+
_v7Lift: 1,
|
|
48997
|
+
_v7Recall: 0,
|
|
48998
|
+
_v7FpRate: 0,
|
|
48999
|
+
_v7Precision: 0,
|
|
49000
|
+
_v8Verdict: "DORMANT",
|
|
49001
|
+
_v8Lift: 1,
|
|
49002
|
+
defaultOff: true
|
|
47473
49003
|
},
|
|
47474
|
-
"
|
|
49004
|
+
"go/error-wrap-without-context": {
|
|
47475
49005
|
recall: 0,
|
|
47476
49006
|
fpRate: 0,
|
|
47477
|
-
ratio:
|
|
49007
|
+
ratio: 1,
|
|
47478
49008
|
precision: 0,
|
|
47479
|
-
lastCalibratedAt: "2026-
|
|
49009
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
47480
49010
|
verdict: "DORMANT",
|
|
47481
|
-
|
|
47482
|
-
|
|
47483
|
-
|
|
49011
|
+
_calibrationNote: "v0.19: new rule (fmt.Errorf wrap with generic message \u2014 needs operation context). Not yet calibrated. Scheduled for v9 calibration.",
|
|
49012
|
+
aiSpecific: true,
|
|
49013
|
+
_v7Verdict: "DORMANT",
|
|
49014
|
+
_v7Lift: 1,
|
|
49015
|
+
_v7Recall: 0,
|
|
49016
|
+
_v7FpRate: 0,
|
|
49017
|
+
_v7Precision: 0,
|
|
49018
|
+
_v8Verdict: "DORMANT",
|
|
49019
|
+
_v8Lift: 1,
|
|
49020
|
+
defaultOff: true
|
|
47484
49021
|
},
|
|
47485
|
-
"
|
|
49022
|
+
"go/nil-slice-vs-empty": {
|
|
47486
49023
|
recall: 0,
|
|
47487
49024
|
fpRate: 0,
|
|
47488
|
-
ratio:
|
|
49025
|
+
ratio: 1,
|
|
47489
49026
|
precision: 0,
|
|
47490
|
-
lastCalibratedAt: "2026-
|
|
49027
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
47491
49028
|
verdict: "DORMANT",
|
|
47492
|
-
|
|
47493
|
-
|
|
47494
|
-
|
|
49029
|
+
_calibrationNote: "v0.19: new rule (Variable declared nil slice but assigned empty slice). Not yet calibrated. Scheduled for v9 calibration.",
|
|
49030
|
+
aiSpecific: true,
|
|
49031
|
+
_v7Verdict: "DORMANT",
|
|
49032
|
+
_v7Lift: 1,
|
|
49033
|
+
_v7Recall: 0,
|
|
49034
|
+
_v7FpRate: 0,
|
|
49035
|
+
_v7Precision: 0,
|
|
49036
|
+
_v8Verdict: "DORMANT",
|
|
49037
|
+
_v8Lift: 1,
|
|
49038
|
+
defaultOff: true
|
|
47495
49039
|
},
|
|
47496
|
-
"
|
|
49040
|
+
"go/struct-tag-inconsistency": {
|
|
47497
49041
|
recall: 0,
|
|
47498
49042
|
fpRate: 0,
|
|
47499
|
-
ratio:
|
|
49043
|
+
ratio: 1,
|
|
47500
49044
|
precision: 0,
|
|
47501
|
-
lastCalibratedAt: "2026-
|
|
49045
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
47502
49046
|
verdict: "DORMANT",
|
|
47503
|
-
|
|
47504
|
-
|
|
47505
|
-
|
|
49047
|
+
_calibrationNote: "v0.19: new rule (Struct fields mix json tag styles). Not yet calibrated. Scheduled for v9 calibration.",
|
|
49048
|
+
aiSpecific: true,
|
|
49049
|
+
_v7Verdict: "DORMANT",
|
|
49050
|
+
_v7Lift: 1,
|
|
49051
|
+
_v7Recall: 0,
|
|
49052
|
+
_v7FpRate: 0,
|
|
49053
|
+
_v7Precision: 0,
|
|
49054
|
+
_v8Verdict: "DORMANT",
|
|
49055
|
+
_v8Lift: 1,
|
|
49056
|
+
defaultOff: true
|
|
47506
49057
|
},
|
|
47507
|
-
"
|
|
49058
|
+
"layout/forced-layout": {
|
|
47508
49059
|
recall: 0,
|
|
47509
49060
|
fpRate: 0,
|
|
47510
49061
|
ratio: 0,
|
|
47511
49062
|
precision: 0,
|
|
47512
|
-
lastCalibratedAt: "2026-
|
|
49063
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
47513
49064
|
verdict: "DORMANT",
|
|
47514
|
-
|
|
47515
|
-
|
|
47516
|
-
|
|
49065
|
+
_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.",
|
|
49066
|
+
aiSpecific: true,
|
|
49067
|
+
_v7Verdict: "DORMANT",
|
|
49068
|
+
_v7Lift: 0,
|
|
49069
|
+
_v7Recall: 0,
|
|
49070
|
+
_v7FpRate: 0,
|
|
49071
|
+
_v7Precision: 0,
|
|
49072
|
+
_v8Verdict: "DORMANT",
|
|
49073
|
+
_v8Lift: 1,
|
|
49074
|
+
defaultOff: true
|
|
47517
49075
|
},
|
|
47518
|
-
"
|
|
47519
|
-
recall:
|
|
47520
|
-
fpRate:
|
|
47521
|
-
ratio:
|
|
47522
|
-
precision: 0.
|
|
47523
|
-
lastCalibratedAt: "2026-
|
|
47524
|
-
verdict: "HYGIENE",
|
|
47525
|
-
_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.",
|
|
47526
|
-
aiSpecific: false
|
|
47527
|
-
},
|
|
47528
|
-
"product/ux-pattern-fragmentation": {
|
|
47529
|
-
recall: 1e-4,
|
|
47530
|
-
fpRate: 0,
|
|
47531
|
-
ratio: 3.09,
|
|
47532
|
-
precision: 0.8,
|
|
47533
|
-
lastCalibratedAt: "2026-06-27T12:00:00Z",
|
|
49076
|
+
"layout/gap-monopoly": {
|
|
49077
|
+
recall: 3e-4,
|
|
49078
|
+
fpRate: 1e-4,
|
|
49079
|
+
ratio: 8859.33,
|
|
49080
|
+
precision: 0.8083,
|
|
49081
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
47534
49082
|
verdict: "USEFUL",
|
|
47535
|
-
_calibrationNote: "
|
|
47536
|
-
aiSpecific:
|
|
49083
|
+
_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).",
|
|
49084
|
+
aiSpecific: false,
|
|
49085
|
+
_v7Verdict: "USEFUL",
|
|
49086
|
+
_v7Lift: 6322.11,
|
|
49087
|
+
_v7Recall: 4e-4,
|
|
49088
|
+
_v7FpRate: 1e-4,
|
|
49089
|
+
_v7Precision: 0.7928,
|
|
49090
|
+
_v8Verdict: "USEFUL",
|
|
49091
|
+
_v8Lift: 99999
|
|
47537
49092
|
},
|
|
47538
|
-
"
|
|
47539
|
-
recall:
|
|
47540
|
-
fpRate:
|
|
47541
|
-
ratio:
|
|
47542
|
-
precision: 0.
|
|
47543
|
-
lastCalibratedAt: "2026-
|
|
47544
|
-
verdict: "
|
|
47545
|
-
_calibrationNote: "
|
|
47546
|
-
aiSpecific: true
|
|
49093
|
+
"layout/math-element-uniformity": {
|
|
49094
|
+
recall: 29e-4,
|
|
49095
|
+
fpRate: 1e-3,
|
|
49096
|
+
ratio: 770.74,
|
|
49097
|
+
precision: 0.7705,
|
|
49098
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
49099
|
+
verdict: "USEFUL",
|
|
49100
|
+
_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).",
|
|
49101
|
+
aiSpecific: true,
|
|
49102
|
+
_v7Verdict: "USEFUL",
|
|
49103
|
+
_v7Lift: 609.32,
|
|
49104
|
+
_v7Recall: 28e-4,
|
|
49105
|
+
_v7FpRate: 12e-4,
|
|
49106
|
+
_v7Precision: 0.7475,
|
|
49107
|
+
_v8Verdict: "USEFUL",
|
|
49108
|
+
_v8Lift: 2211.5
|
|
47547
49109
|
},
|
|
47548
|
-
"
|
|
47549
|
-
recall:
|
|
47550
|
-
fpRate:
|
|
47551
|
-
ratio:
|
|
47552
|
-
precision: 0.
|
|
47553
|
-
lastCalibratedAt: "2026-
|
|
49110
|
+
"layout/math-grid-uniformity": {
|
|
49111
|
+
recall: 3e-4,
|
|
49112
|
+
fpRate: 1e-4,
|
|
49113
|
+
ratio: 5839.98,
|
|
49114
|
+
precision: 0.7182,
|
|
49115
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
47554
49116
|
verdict: "USEFUL",
|
|
47555
|
-
_calibrationNote: "
|
|
47556
|
-
aiSpecific:
|
|
49117
|
+
_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).",
|
|
49118
|
+
aiSpecific: true,
|
|
49119
|
+
_v7Verdict: "USEFUL",
|
|
49120
|
+
_v7Lift: 4222.91,
|
|
49121
|
+
_v7Recall: 3e-4,
|
|
49122
|
+
_v7FpRate: 2e-4,
|
|
49123
|
+
_v7Precision: 0.6907,
|
|
49124
|
+
_v8Verdict: "USEFUL",
|
|
49125
|
+
_v8Lift: 63384.92
|
|
47557
49126
|
},
|
|
47558
|
-
"
|
|
47559
|
-
recall:
|
|
47560
|
-
fpRate:
|
|
47561
|
-
ratio:
|
|
47562
|
-
precision: 0.
|
|
47563
|
-
lastCalibratedAt: "2026-
|
|
47564
|
-
verdict: "
|
|
47565
|
-
_calibrationNote: "
|
|
47566
|
-
|
|
47567
|
-
|
|
49127
|
+
"layout/spacing-grid": {
|
|
49128
|
+
recall: 2e-4,
|
|
49129
|
+
fpRate: 2e-4,
|
|
49130
|
+
ratio: 4051.29,
|
|
49131
|
+
precision: 0.6429,
|
|
49132
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
49133
|
+
verdict: "USEFUL",
|
|
49134
|
+
_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).",
|
|
49135
|
+
aiSpecific: false,
|
|
49136
|
+
_v7Verdict: "USEFUL",
|
|
49137
|
+
_v7Lift: 8831,
|
|
49138
|
+
_v7Recall: 2e-4,
|
|
49139
|
+
_v7FpRate: 1e-4,
|
|
49140
|
+
_v7Precision: 0.7222,
|
|
49141
|
+
_v8Verdict: "USEFUL",
|
|
49142
|
+
_v8Lift: 1562.77
|
|
47568
49143
|
},
|
|
47569
|
-
"
|
|
47570
|
-
recall:
|
|
49144
|
+
"logic/bayesian-conditional": {
|
|
49145
|
+
recall: 0,
|
|
47571
49146
|
fpRate: 0,
|
|
47572
|
-
ratio:
|
|
47573
|
-
precision: 0
|
|
47574
|
-
lastCalibratedAt: "2026-
|
|
49147
|
+
ratio: 0,
|
|
49148
|
+
precision: 0,
|
|
49149
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
49150
|
+
verdict: "DORMANT",
|
|
49151
|
+
_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.",
|
|
49152
|
+
aiSpecific: true,
|
|
49153
|
+
_v7Verdict: "DORMANT",
|
|
49154
|
+
_v7Lift: 0,
|
|
49155
|
+
_v7Recall: 0,
|
|
49156
|
+
_v7FpRate: 0,
|
|
49157
|
+
_v7Precision: 0,
|
|
49158
|
+
_v8Verdict: "DORMANT",
|
|
49159
|
+
_v8Lift: 1,
|
|
49160
|
+
defaultOff: true
|
|
49161
|
+
},
|
|
49162
|
+
"logic/boundary-violation": {
|
|
49163
|
+
recall: 0.0274,
|
|
49164
|
+
fpRate: 0.0137,
|
|
49165
|
+
ratio: 51.32,
|
|
49166
|
+
precision: 0.7006,
|
|
49167
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
47575
49168
|
verdict: "USEFUL",
|
|
47576
|
-
_calibrationNote: "
|
|
47577
|
-
aiSpecific:
|
|
49169
|
+
_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).",
|
|
49170
|
+
aiSpecific: false,
|
|
49171
|
+
_v7Verdict: "USEFUL",
|
|
49172
|
+
_v7Lift: 37.42,
|
|
49173
|
+
_v7Recall: 0.0265,
|
|
49174
|
+
_v7FpRate: 0.0176,
|
|
49175
|
+
_v7Precision: 0.6601,
|
|
49176
|
+
_v8Verdict: "USEFUL",
|
|
49177
|
+
_v8Lift: 298.57
|
|
47578
49178
|
},
|
|
47579
49179
|
"logic/ghost-defensive": {
|
|
47580
49180
|
recall: 1e-4,
|
|
47581
49181
|
fpRate: 0,
|
|
47582
|
-
ratio:
|
|
47583
|
-
precision: 0.
|
|
47584
|
-
lastCalibratedAt: "2026-
|
|
49182
|
+
ratio: 112035.56,
|
|
49183
|
+
precision: 0.8889,
|
|
49184
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
47585
49185
|
verdict: "USEFUL",
|
|
47586
|
-
_calibrationNote: "
|
|
47587
|
-
aiSpecific: true
|
|
49186
|
+
_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.",
|
|
49187
|
+
aiSpecific: true,
|
|
49188
|
+
_v7Verdict: "USEFUL",
|
|
49189
|
+
_v7Lift: 80917.5,
|
|
49190
|
+
_v7Recall: 1e-4,
|
|
49191
|
+
_v7FpRate: 0,
|
|
49192
|
+
_v7Precision: 0.8824,
|
|
49193
|
+
_v8Verdict: "USEFUL",
|
|
49194
|
+
_v8Lift: 99999,
|
|
49195
|
+
defaultOff: false
|
|
47588
49196
|
},
|
|
47589
|
-
"
|
|
47590
|
-
recall: 0,
|
|
47591
|
-
fpRate: 0,
|
|
47592
|
-
ratio:
|
|
47593
|
-
precision: 0.
|
|
47594
|
-
lastCalibratedAt: "2026-
|
|
47595
|
-
verdict: "
|
|
47596
|
-
_calibrationNote: "
|
|
47597
|
-
aiSpecific: false
|
|
49197
|
+
"logic/heaps-deviation": {
|
|
49198
|
+
recall: 0.0126,
|
|
49199
|
+
fpRate: 0.0178,
|
|
49200
|
+
ratio: 25.54,
|
|
49201
|
+
precision: 0.4536,
|
|
49202
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
49203
|
+
verdict: "OK",
|
|
49204
|
+
_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).",
|
|
49205
|
+
aiSpecific: false,
|
|
49206
|
+
_v7Verdict: "USEFUL",
|
|
49207
|
+
_v7Lift: 41.22,
|
|
49208
|
+
_v7Recall: 0.0123,
|
|
49209
|
+
_v7FpRate: 0.0132,
|
|
49210
|
+
_v7Precision: 0.5461,
|
|
49211
|
+
_v8Verdict: "OK",
|
|
49212
|
+
_v8Lift: 9.36
|
|
47598
49213
|
},
|
|
47599
|
-
"
|
|
47600
|
-
recall:
|
|
47601
|
-
fpRate:
|
|
47602
|
-
ratio:
|
|
47603
|
-
precision:
|
|
47604
|
-
lastCalibratedAt: "2026-
|
|
49214
|
+
"logic/key-prop-missing": {
|
|
49215
|
+
recall: 16e-4,
|
|
49216
|
+
fpRate: 11e-4,
|
|
49217
|
+
ratio: 574.52,
|
|
49218
|
+
precision: 0.629,
|
|
49219
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
47605
49220
|
verdict: "USEFUL",
|
|
47606
|
-
_calibrationNote: "
|
|
47607
|
-
aiSpecific:
|
|
49221
|
+
_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).",
|
|
49222
|
+
aiSpecific: false,
|
|
49223
|
+
_v7Verdict: "USEFUL",
|
|
49224
|
+
_v7Lift: 458.26,
|
|
49225
|
+
_v7Recall: 18e-4,
|
|
49226
|
+
_v7FpRate: 14e-4,
|
|
49227
|
+
_v7Precision: 0.6246,
|
|
49228
|
+
_v8Verdict: "USEFUL",
|
|
49229
|
+
_v8Lift: 1760.69
|
|
47608
49230
|
},
|
|
47609
|
-
"
|
|
47610
|
-
recall:
|
|
47611
|
-
fpRate:
|
|
47612
|
-
ratio:
|
|
47613
|
-
precision: 0.
|
|
47614
|
-
lastCalibratedAt: "2026-
|
|
47615
|
-
verdict: "
|
|
47616
|
-
_calibrationNote: "
|
|
47617
|
-
aiSpecific:
|
|
49231
|
+
"logic/math-any-density": {
|
|
49232
|
+
recall: 17e-4,
|
|
49233
|
+
fpRate: 13e-4,
|
|
49234
|
+
ratio: 464.59,
|
|
49235
|
+
precision: 0.6027,
|
|
49236
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
49237
|
+
verdict: "USEFUL",
|
|
49238
|
+
_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).",
|
|
49239
|
+
aiSpecific: true,
|
|
49240
|
+
_v7Verdict: "USEFUL",
|
|
49241
|
+
_v7Lift: 448.16,
|
|
49242
|
+
_v7Recall: 16e-4,
|
|
49243
|
+
_v7FpRate: 13e-4,
|
|
49244
|
+
_v7Precision: 0.6035,
|
|
49245
|
+
_v8Verdict: "USEFUL",
|
|
49246
|
+
_v8Lift: 515
|
|
47618
49247
|
},
|
|
47619
|
-
"
|
|
47620
|
-
recall:
|
|
47621
|
-
fpRate:
|
|
47622
|
-
ratio:
|
|
47623
|
-
precision: 0.
|
|
47624
|
-
lastCalibratedAt: "2026-
|
|
49248
|
+
"logic/math-console-log-storm": {
|
|
49249
|
+
recall: 65e-4,
|
|
49250
|
+
fpRate: 11e-4,
|
|
49251
|
+
ratio: 794.4,
|
|
49252
|
+
precision: 0.8729,
|
|
49253
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
47625
49254
|
verdict: "USEFUL",
|
|
47626
|
-
_calibrationNote: "
|
|
47627
|
-
aiSpecific: true
|
|
49255
|
+
_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).",
|
|
49256
|
+
aiSpecific: true,
|
|
49257
|
+
_v7Verdict: "USEFUL",
|
|
49258
|
+
_v7Lift: 852.3,
|
|
49259
|
+
_v7Recall: 71e-4,
|
|
49260
|
+
_v7FpRate: 11e-4,
|
|
49261
|
+
_v7Precision: 0.8968,
|
|
49262
|
+
_v8Verdict: "USEFUL",
|
|
49263
|
+
_v8Lift: 595.24
|
|
47628
49264
|
},
|
|
47629
|
-
"
|
|
49265
|
+
"logic/math-gini-class-usage": {
|
|
47630
49266
|
recall: 13e-4,
|
|
47631
|
-
fpRate:
|
|
47632
|
-
ratio:
|
|
47633
|
-
precision: 0.
|
|
47634
|
-
lastCalibratedAt: "2026-
|
|
47635
|
-
verdict: "OK",
|
|
47636
|
-
_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.",
|
|
47637
|
-
aiSpecific: true
|
|
47638
|
-
},
|
|
47639
|
-
"visual/radius-scale-violation": {
|
|
47640
|
-
recall: 4e-4,
|
|
47641
|
-
fpRate: 0,
|
|
47642
|
-
ratio: 24.7,
|
|
47643
|
-
precision: 0.9697,
|
|
47644
|
-
lastCalibratedAt: "2026-06-27T12:00:00Z",
|
|
47645
|
-
verdict: "HYGIENE",
|
|
47646
|
-
_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.",
|
|
47647
|
-
aiSpecific: false
|
|
47648
|
-
},
|
|
47649
|
-
"test/fake-placeholder": {
|
|
47650
|
-
recall: 53e-4,
|
|
47651
|
-
fpRate: 19e-4,
|
|
47652
|
-
ratio: 2.82,
|
|
47653
|
-
precision: 0.7854,
|
|
47654
|
-
lastCalibratedAt: "2026-06-27T12:00:00Z",
|
|
49267
|
+
fpRate: 2e-4,
|
|
49268
|
+
ratio: 4648.6,
|
|
49269
|
+
precision: 0.8852,
|
|
49270
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
47655
49271
|
verdict: "USEFUL",
|
|
47656
|
-
_calibrationNote: "
|
|
47657
|
-
aiSpecific: true
|
|
47658
|
-
|
|
47659
|
-
|
|
47660
|
-
|
|
47661
|
-
|
|
47662
|
-
|
|
47663
|
-
|
|
47664
|
-
|
|
47665
|
-
verdict: "HYGIENE",
|
|
47666
|
-
_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.",
|
|
47667
|
-
aiSpecific: false
|
|
47668
|
-
},
|
|
47669
|
-
"perf/cls-image": {
|
|
47670
|
-
recall: 2e-4,
|
|
47671
|
-
fpRate: 3e-4,
|
|
47672
|
-
ratio: 0.8,
|
|
47673
|
-
precision: 0.5104,
|
|
47674
|
-
lastCalibratedAt: "2026-06-27T12:00:00Z",
|
|
47675
|
-
verdict: "HYGIENE",
|
|
47676
|
-
_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.",
|
|
47677
|
-
aiSpecific: false
|
|
47678
|
-
},
|
|
47679
|
-
"layout/gap-monopoly": {
|
|
47680
|
-
recall: 4e-4,
|
|
47681
|
-
fpRate: 1e-4,
|
|
47682
|
-
ratio: 2.95,
|
|
47683
|
-
precision: 0.7928,
|
|
47684
|
-
lastCalibratedAt: "2026-06-27T12:00:00Z",
|
|
47685
|
-
verdict: "HYGIENE",
|
|
47686
|
-
_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.",
|
|
47687
|
-
aiSpecific: false
|
|
47688
|
-
},
|
|
47689
|
-
"visual/spacing-scale-violation": {
|
|
47690
|
-
recall: 83e-4,
|
|
47691
|
-
fpRate: 39e-4,
|
|
47692
|
-
ratio: 2.13,
|
|
47693
|
-
precision: 0.7342,
|
|
47694
|
-
lastCalibratedAt: "2026-06-27T12:00:00Z",
|
|
47695
|
-
verdict: "HYGIENE",
|
|
47696
|
-
_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.",
|
|
47697
|
-
aiSpecific: false
|
|
47698
|
-
},
|
|
47699
|
-
"visual/inline-style-dominance": {
|
|
47700
|
-
recall: 96e-4,
|
|
47701
|
-
fpRate: 66e-4,
|
|
47702
|
-
ratio: 1.46,
|
|
47703
|
-
precision: 0.6535,
|
|
47704
|
-
lastCalibratedAt: "2026-06-27T12:00:00Z",
|
|
47705
|
-
verdict: "HYGIENE",
|
|
47706
|
-
_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.",
|
|
47707
|
-
aiSpecific: false
|
|
49272
|
+
_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).",
|
|
49273
|
+
aiSpecific: true,
|
|
49274
|
+
_v7Verdict: "USEFUL",
|
|
49275
|
+
_v7Lift: 3388.64,
|
|
49276
|
+
_v7Recall: 13e-4,
|
|
49277
|
+
_v7FpRate: 3e-4,
|
|
49278
|
+
_v7Precision: 0.8683,
|
|
49279
|
+
_v8Verdict: "USEFUL",
|
|
49280
|
+
_v8Lift: 67541.31
|
|
47708
49281
|
},
|
|
47709
|
-
"
|
|
49282
|
+
"logic/math-variable-name-entropy": {
|
|
47710
49283
|
recall: 2e-4,
|
|
47711
49284
|
fpRate: 1e-4,
|
|
47712
|
-
ratio:
|
|
47713
|
-
precision: 0.
|
|
47714
|
-
lastCalibratedAt: "2026-
|
|
47715
|
-
verdict: "
|
|
47716
|
-
_calibrationNote: "
|
|
47717
|
-
aiSpecific: false
|
|
47718
|
-
|
|
47719
|
-
|
|
47720
|
-
|
|
47721
|
-
|
|
47722
|
-
|
|
47723
|
-
|
|
47724
|
-
|
|
47725
|
-
verdict: "HYGIENE",
|
|
47726
|
-
_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.",
|
|
47727
|
-
aiSpecific: false
|
|
49285
|
+
ratio: 4548.81,
|
|
49286
|
+
precision: 0.6316,
|
|
49287
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
49288
|
+
verdict: "USEFUL",
|
|
49289
|
+
_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).",
|
|
49290
|
+
aiSpecific: false,
|
|
49291
|
+
_v7Verdict: "USEFUL",
|
|
49292
|
+
_v7Lift: 4096.07,
|
|
49293
|
+
_v7Recall: 2e-4,
|
|
49294
|
+
_v7FpRate: 1e-4,
|
|
49295
|
+
_v7Precision: 0.5806,
|
|
49296
|
+
_v8Verdict: "USEFUL",
|
|
49297
|
+
_v8Lift: 5548.85
|
|
47728
49298
|
},
|
|
47729
|
-
"
|
|
47730
|
-
recall:
|
|
47731
|
-
fpRate:
|
|
47732
|
-
ratio:
|
|
47733
|
-
precision: 0.
|
|
47734
|
-
lastCalibratedAt: "2026-
|
|
49299
|
+
"logic/optimistic-no-rollback": {
|
|
49300
|
+
recall: 12e-4,
|
|
49301
|
+
fpRate: 2e-4,
|
|
49302
|
+
ratio: 3523.57,
|
|
49303
|
+
precision: 0.8527,
|
|
49304
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
47735
49305
|
verdict: "USEFUL",
|
|
47736
|
-
_calibrationNote: "
|
|
47737
|
-
aiSpecific: true
|
|
49306
|
+
_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).",
|
|
49307
|
+
aiSpecific: true,
|
|
49308
|
+
_v7Verdict: "USEFUL",
|
|
49309
|
+
_v7Lift: 2519.02,
|
|
49310
|
+
_v7Recall: 12e-4,
|
|
49311
|
+
_v7FpRate: 3e-4,
|
|
49312
|
+
_v7Precision: 0.824,
|
|
49313
|
+
_v8Verdict: "USEFUL",
|
|
49314
|
+
_v8Lift: 67726.36
|
|
47738
49315
|
},
|
|
47739
|
-
"logic/
|
|
49316
|
+
"logic/qwik-hook-leak": {
|
|
47740
49317
|
recall: 0,
|
|
47741
49318
|
fpRate: 0,
|
|
47742
49319
|
ratio: 0,
|
|
47743
49320
|
precision: 0,
|
|
47744
|
-
lastCalibratedAt: "2026-
|
|
49321
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
47745
49322
|
verdict: "DORMANT",
|
|
47746
|
-
|
|
47747
|
-
|
|
47748
|
-
|
|
49323
|
+
_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.",
|
|
49324
|
+
aiSpecific: true,
|
|
49325
|
+
_v7Verdict: "DORMANT",
|
|
49326
|
+
_v7Lift: 0,
|
|
49327
|
+
_v7Recall: 0,
|
|
49328
|
+
_v7FpRate: 0,
|
|
49329
|
+
_v7Precision: 0,
|
|
49330
|
+
_v8Verdict: "DORMANT",
|
|
49331
|
+
_v8Lift: 1,
|
|
49332
|
+
defaultOff: true
|
|
47749
49333
|
},
|
|
47750
|
-
"logic/
|
|
47751
|
-
recall:
|
|
47752
|
-
fpRate:
|
|
47753
|
-
ratio:
|
|
47754
|
-
precision: 0.
|
|
47755
|
-
lastCalibratedAt: "2026-
|
|
47756
|
-
verdict: "
|
|
47757
|
-
_calibrationNote: "
|
|
47758
|
-
aiSpecific:
|
|
47759
|
-
|
|
47760
|
-
|
|
47761
|
-
|
|
47762
|
-
|
|
47763
|
-
|
|
47764
|
-
|
|
47765
|
-
|
|
47766
|
-
verdict: "HYGIENE",
|
|
47767
|
-
_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.",
|
|
47768
|
-
aiSpecific: false
|
|
49334
|
+
"logic/reactive-hook-soup": {
|
|
49335
|
+
recall: 41e-4,
|
|
49336
|
+
fpRate: 6e-4,
|
|
49337
|
+
ratio: 1370.15,
|
|
49338
|
+
precision: 0.8805,
|
|
49339
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
49340
|
+
verdict: "USEFUL",
|
|
49341
|
+
_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).",
|
|
49342
|
+
aiSpecific: true,
|
|
49343
|
+
_v7Verdict: "USEFUL",
|
|
49344
|
+
_v7Lift: 959.64,
|
|
49345
|
+
_v7Recall: 38e-4,
|
|
49346
|
+
_v7FpRate: 9e-4,
|
|
49347
|
+
_v7Precision: 0.8476,
|
|
49348
|
+
_v8Verdict: "USEFUL",
|
|
49349
|
+
_v8Lift: 99999
|
|
47769
49350
|
},
|
|
47770
49351
|
"logic/zipf-slope-anomaly": {
|
|
47771
|
-
recall: 0.
|
|
47772
|
-
fpRate:
|
|
47773
|
-
ratio:
|
|
47774
|
-
precision: 0.
|
|
47775
|
-
lastCalibratedAt: "2026-
|
|
47776
|
-
verdict: "
|
|
47777
|
-
_calibrationNote: "
|
|
47778
|
-
aiSpecific: false
|
|
49352
|
+
recall: 0.0168,
|
|
49353
|
+
fpRate: 0.0111,
|
|
49354
|
+
ratio: 57.13,
|
|
49355
|
+
precision: 0.6369,
|
|
49356
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
49357
|
+
verdict: "USEFUL",
|
|
49358
|
+
_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).",
|
|
49359
|
+
aiSpecific: false,
|
|
49360
|
+
_v7Verdict: "USEFUL",
|
|
49361
|
+
_v7Lift: 79.75,
|
|
49362
|
+
_v7Recall: 0.0157,
|
|
49363
|
+
_v7FpRate: 88e-4,
|
|
49364
|
+
_v7Precision: 0.6983,
|
|
49365
|
+
_v8Verdict: "USEFUL",
|
|
49366
|
+
_v8Lift: 28.59
|
|
47779
49367
|
},
|
|
47780
|
-
"
|
|
47781
|
-
recall:
|
|
49368
|
+
"logic/zombie-state": {
|
|
49369
|
+
recall: 1e-4,
|
|
47782
49370
|
fpRate: 0,
|
|
47783
|
-
ratio:
|
|
47784
|
-
precision: 0.
|
|
47785
|
-
lastCalibratedAt: "2026-
|
|
47786
|
-
verdict: "
|
|
47787
|
-
_calibrationNote: "
|
|
47788
|
-
aiSpecific: true
|
|
49371
|
+
ratio: 119891.71,
|
|
49372
|
+
precision: 0.9512,
|
|
49373
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
49374
|
+
verdict: "USEFUL",
|
|
49375
|
+
_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).",
|
|
49376
|
+
aiSpecific: true,
|
|
49377
|
+
_v7Verdict: "USEFUL",
|
|
49378
|
+
_v7Lift: 84652.15,
|
|
49379
|
+
_v7Recall: 1e-4,
|
|
49380
|
+
_v7FpRate: 0,
|
|
49381
|
+
_v7Precision: 0.9231,
|
|
49382
|
+
_v8Verdict: "USEFUL",
|
|
49383
|
+
_v8Lift: 99999
|
|
47789
49384
|
},
|
|
47790
|
-
"
|
|
47791
|
-
recall:
|
|
47792
|
-
fpRate:
|
|
47793
|
-
ratio:
|
|
47794
|
-
precision: 0.
|
|
47795
|
-
lastCalibratedAt: "2026-
|
|
47796
|
-
verdict: "
|
|
47797
|
-
_calibrationNote: "
|
|
47798
|
-
aiSpecific:
|
|
49385
|
+
"perf/cls-image": {
|
|
49386
|
+
recall: 2e-4,
|
|
49387
|
+
fpRate: 2e-4,
|
|
49388
|
+
ratio: 2895.78,
|
|
49389
|
+
precision: 0.5514,
|
|
49390
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
49391
|
+
verdict: "USEFUL",
|
|
49392
|
+
_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).",
|
|
49393
|
+
aiSpecific: false,
|
|
49394
|
+
_v7Verdict: "USEFUL",
|
|
49395
|
+
_v7Lift: 1991.85,
|
|
49396
|
+
_v7Recall: 2e-4,
|
|
49397
|
+
_v7FpRate: 3e-4,
|
|
49398
|
+
_v7Precision: 0.5104,
|
|
49399
|
+
_v8Verdict: "USEFUL",
|
|
49400
|
+
_v8Lift: 62424.55
|
|
47799
49401
|
},
|
|
47800
|
-
"
|
|
47801
|
-
recall: 0.
|
|
47802
|
-
fpRate:
|
|
47803
|
-
ratio:
|
|
47804
|
-
precision: 0.
|
|
47805
|
-
lastCalibratedAt: "2026-
|
|
47806
|
-
verdict: "
|
|
47807
|
-
_calibrationNote: "
|
|
47808
|
-
|
|
47809
|
-
|
|
49402
|
+
"perf/css-bloat": {
|
|
49403
|
+
recall: 0.0126,
|
|
49404
|
+
fpRate: 24e-4,
|
|
49405
|
+
ratio: 365.63,
|
|
49406
|
+
precision: 0.8616,
|
|
49407
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
49408
|
+
verdict: "USEFUL",
|
|
49409
|
+
_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).",
|
|
49410
|
+
aiSpecific: false,
|
|
49411
|
+
_v7Verdict: "USEFUL",
|
|
49412
|
+
_v7Lift: 256.1,
|
|
49413
|
+
_v7Recall: 0.0118,
|
|
49414
|
+
_v7FpRate: 32e-4,
|
|
49415
|
+
_v7Precision: 0.8252,
|
|
49416
|
+
_v8Verdict: "USEFUL",
|
|
49417
|
+
_v8Lift: 22813.54
|
|
47810
49418
|
},
|
|
47811
|
-
"
|
|
49419
|
+
"perf/halstead-anomaly": {
|
|
47812
49420
|
recall: 0,
|
|
47813
49421
|
fpRate: 0,
|
|
47814
|
-
ratio:
|
|
47815
|
-
precision: 0.
|
|
47816
|
-
lastCalibratedAt: "2026-
|
|
49422
|
+
ratio: 75624,
|
|
49423
|
+
precision: 0.6,
|
|
49424
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
47817
49425
|
verdict: "USEFUL",
|
|
47818
|
-
_calibrationNote: "
|
|
47819
|
-
aiSpecific: true
|
|
49426
|
+
_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).",
|
|
49427
|
+
aiSpecific: true,
|
|
49428
|
+
_v7Verdict: "USEFUL",
|
|
49429
|
+
_v7Lift: 137559.75,
|
|
49430
|
+
_v7Recall: 0,
|
|
49431
|
+
_v7FpRate: 0,
|
|
49432
|
+
_v7Precision: 0.75,
|
|
49433
|
+
_v8Verdict: "INVERTED",
|
|
49434
|
+
_v8Lift: 0
|
|
47820
49435
|
},
|
|
47821
|
-
"
|
|
47822
|
-
recall:
|
|
47823
|
-
fpRate:
|
|
47824
|
-
ratio:
|
|
47825
|
-
precision: 0.
|
|
47826
|
-
lastCalibratedAt: "2026-
|
|
47827
|
-
verdict: "
|
|
47828
|
-
_calibrationNote: "
|
|
47829
|
-
|
|
47830
|
-
|
|
49436
|
+
"product/terminology-drift": {
|
|
49437
|
+
recall: 91e-4,
|
|
49438
|
+
fpRate: 21e-4,
|
|
49439
|
+
ratio: 397.75,
|
|
49440
|
+
precision: 0.8347,
|
|
49441
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
49442
|
+
verdict: "USEFUL",
|
|
49443
|
+
_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).",
|
|
49444
|
+
aiSpecific: false,
|
|
49445
|
+
_v7Verdict: "USEFUL",
|
|
49446
|
+
_v7Lift: 280.09,
|
|
49447
|
+
_v7Recall: 86e-4,
|
|
49448
|
+
_v7FpRate: 28e-4,
|
|
49449
|
+
_v7Precision: 0.7956,
|
|
49450
|
+
_v8Verdict: "USEFUL",
|
|
49451
|
+
_v8Lift: 8477.9
|
|
47831
49452
|
},
|
|
47832
|
-
"
|
|
47833
|
-
recall:
|
|
47834
|
-
fpRate:
|
|
47835
|
-
ratio:
|
|
47836
|
-
precision: 0.
|
|
47837
|
-
lastCalibratedAt: "2026-
|
|
47838
|
-
verdict: "
|
|
47839
|
-
_calibrationNote: "
|
|
47840
|
-
|
|
47841
|
-
|
|
49453
|
+
"product/ux-pattern-fragmentation": {
|
|
49454
|
+
recall: 1e-4,
|
|
49455
|
+
fpRate: 0,
|
|
49456
|
+
ratio: 22864.4,
|
|
49457
|
+
precision: 0.8163,
|
|
49458
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
49459
|
+
verdict: "USEFUL",
|
|
49460
|
+
_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).",
|
|
49461
|
+
aiSpecific: true,
|
|
49462
|
+
_v7Verdict: "USEFUL",
|
|
49463
|
+
_v7Lift: 18341.3,
|
|
49464
|
+
_v7Recall: 1e-4,
|
|
49465
|
+
_v7FpRate: 0,
|
|
49466
|
+
_v7Precision: 0.8,
|
|
49467
|
+
_v8Verdict: "USEFUL",
|
|
49468
|
+
_v8Lift: 61037.33
|
|
47842
49469
|
},
|
|
47843
|
-
"
|
|
47844
|
-
recall:
|
|
49470
|
+
"rust/stringly-typed": {
|
|
49471
|
+
recall: 2e-4,
|
|
47845
49472
|
fpRate: 0,
|
|
47846
|
-
ratio:
|
|
47847
|
-
precision: 0.
|
|
47848
|
-
lastCalibratedAt: "2026-
|
|
47849
|
-
verdict: "
|
|
47850
|
-
_calibrationNote: "
|
|
47851
|
-
|
|
47852
|
-
|
|
49473
|
+
ratio: 24735.12,
|
|
49474
|
+
precision: 0.8831,
|
|
49475
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
49476
|
+
verdict: "USEFUL",
|
|
49477
|
+
_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).",
|
|
49478
|
+
aiSpecific: true,
|
|
49479
|
+
_v7Verdict: "DORMANT",
|
|
49480
|
+
_v7Lift: 1,
|
|
49481
|
+
_v7Recall: 0,
|
|
49482
|
+
_v7FpRate: 0,
|
|
49483
|
+
_v7Precision: 0,
|
|
49484
|
+
_v8Verdict: "USEFUL",
|
|
49485
|
+
_v8Lift: 6737.89
|
|
47853
49486
|
},
|
|
47854
|
-
"
|
|
49487
|
+
"rust/todo-macro": {
|
|
49488
|
+
recall: 1e-4,
|
|
49489
|
+
fpRate: 7e-4,
|
|
49490
|
+
ratio: 210.08,
|
|
49491
|
+
precision: 0.1392,
|
|
49492
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
49493
|
+
verdict: "OK",
|
|
49494
|
+
_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).",
|
|
49495
|
+
aiSpecific: true,
|
|
49496
|
+
_v7Verdict: "DORMANT",
|
|
49497
|
+
_v7Lift: 1,
|
|
49498
|
+
_v7Recall: 0,
|
|
49499
|
+
_v7FpRate: 0,
|
|
49500
|
+
_v7Precision: 0,
|
|
49501
|
+
_v8Verdict: "OK",
|
|
49502
|
+
_v8Lift: 57.23
|
|
49503
|
+
},
|
|
49504
|
+
"rust/unused-pub-fn": {
|
|
47855
49505
|
recall: 0,
|
|
47856
49506
|
fpRate: 0,
|
|
47857
|
-
ratio:
|
|
47858
|
-
precision: 0,
|
|
47859
|
-
lastCalibratedAt: "2026-
|
|
49507
|
+
ratio: 10803.43,
|
|
49508
|
+
precision: 0.3,
|
|
49509
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
47860
49510
|
verdict: "OK",
|
|
47861
|
-
_calibrationNote: "v0.
|
|
47862
|
-
aiSpecific: true
|
|
49511
|
+
_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).",
|
|
49512
|
+
aiSpecific: true,
|
|
49513
|
+
_v7Verdict: "DORMANT",
|
|
49514
|
+
_v7Lift: 1,
|
|
49515
|
+
_v7Recall: 0,
|
|
49516
|
+
_v7FpRate: 0,
|
|
49517
|
+
_v7Precision: 0,
|
|
49518
|
+
_v8Verdict: "OK",
|
|
49519
|
+
_v8Lift: 2942.87
|
|
47863
49520
|
},
|
|
47864
|
-
"
|
|
47865
|
-
recall:
|
|
47866
|
-
fpRate:
|
|
47867
|
-
ratio:
|
|
47868
|
-
precision: 0.
|
|
47869
|
-
lastCalibratedAt: "2026-
|
|
49521
|
+
"rust/unwrap-in-production": {
|
|
49522
|
+
recall: 8e-3,
|
|
49523
|
+
fpRate: 77e-4,
|
|
49524
|
+
ratio: 70.81,
|
|
49525
|
+
precision: 0.5475,
|
|
49526
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
47870
49527
|
verdict: "USEFUL",
|
|
47871
|
-
_calibrationNote: "
|
|
47872
|
-
aiSpecific: true
|
|
49528
|
+
_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).",
|
|
49529
|
+
aiSpecific: true,
|
|
49530
|
+
_v7Verdict: "DORMANT",
|
|
49531
|
+
_v7Lift: 1,
|
|
49532
|
+
_v7Recall: 0,
|
|
49533
|
+
_v7FpRate: 0,
|
|
49534
|
+
_v7Precision: 0,
|
|
49535
|
+
_v8Verdict: "USEFUL",
|
|
49536
|
+
_v8Lift: 19.29
|
|
47873
49537
|
},
|
|
47874
|
-
"
|
|
47875
|
-
recall:
|
|
47876
|
-
fpRate:
|
|
47877
|
-
ratio:
|
|
47878
|
-
precision: 0.
|
|
47879
|
-
lastCalibratedAt: "2026-
|
|
49538
|
+
"security/dangerous-cors": {
|
|
49539
|
+
recall: 5e-4,
|
|
49540
|
+
fpRate: 4e-4,
|
|
49541
|
+
ratio: 1721.87,
|
|
49542
|
+
precision: 0.6079,
|
|
49543
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
47880
49544
|
verdict: "USEFUL",
|
|
47881
|
-
_calibrationNote: "
|
|
47882
|
-
aiSpecific: true
|
|
49545
|
+
_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).",
|
|
49546
|
+
aiSpecific: true,
|
|
49547
|
+
_v7Verdict: "USEFUL",
|
|
49548
|
+
_v7Lift: 1257.16,
|
|
49549
|
+
_v7Recall: 5e-4,
|
|
49550
|
+
_v7FpRate: 5e-4,
|
|
49551
|
+
_v7Precision: 0.5758,
|
|
49552
|
+
_v8Verdict: "USEFUL",
|
|
49553
|
+
_v8Lift: 11365.57
|
|
47883
49554
|
},
|
|
47884
|
-
"
|
|
47885
|
-
recall:
|
|
47886
|
-
fpRate:
|
|
47887
|
-
ratio:
|
|
47888
|
-
precision: 0.
|
|
47889
|
-
lastCalibratedAt: "2026-
|
|
49555
|
+
"security/eval": {
|
|
49556
|
+
recall: 1e-4,
|
|
49557
|
+
fpRate: 2e-4,
|
|
49558
|
+
ratio: 1929.18,
|
|
49559
|
+
precision: 0.4286,
|
|
49560
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
49561
|
+
verdict: "OK",
|
|
49562
|
+
_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).",
|
|
49563
|
+
aiSpecific: false,
|
|
49564
|
+
_v7Verdict: "DORMANT",
|
|
49565
|
+
_v7Lift: 1,
|
|
49566
|
+
_v7Recall: 0,
|
|
49567
|
+
_v7FpRate: 0,
|
|
49568
|
+
_v7Precision: 0,
|
|
49569
|
+
_v8Verdict: "OK",
|
|
49570
|
+
_v8Lift: 525.51
|
|
49571
|
+
},
|
|
49572
|
+
"security/exposed-env-var": {
|
|
49573
|
+
recall: 6e-4,
|
|
49574
|
+
fpRate: 5e-4,
|
|
49575
|
+
ratio: 1055.81,
|
|
49576
|
+
precision: 0.5696,
|
|
49577
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
47890
49578
|
verdict: "USEFUL",
|
|
47891
|
-
_calibrationNote: "
|
|
47892
|
-
aiSpecific:
|
|
49579
|
+
_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).",
|
|
49580
|
+
aiSpecific: false,
|
|
49581
|
+
_v7Verdict: "USEFUL",
|
|
49582
|
+
_v7Lift: 790.5,
|
|
49583
|
+
_v7Recall: 6e-4,
|
|
49584
|
+
_v7FpRate: 7e-4,
|
|
49585
|
+
_v7Precision: 0.5387,
|
|
49586
|
+
_v8Verdict: "USEFUL",
|
|
49587
|
+
_v8Lift: 4716.52
|
|
47893
49588
|
},
|
|
47894
|
-
"
|
|
47895
|
-
recall:
|
|
49589
|
+
"security/fail-open-auth": {
|
|
49590
|
+
recall: 0,
|
|
47896
49591
|
fpRate: 0,
|
|
47897
|
-
ratio:
|
|
47898
|
-
precision:
|
|
47899
|
-
lastCalibratedAt: "2026-
|
|
49592
|
+
ratio: 99999,
|
|
49593
|
+
precision: 1,
|
|
49594
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
47900
49595
|
verdict: "USEFUL",
|
|
47901
|
-
_calibrationNote: "
|
|
47902
|
-
aiSpecific: true
|
|
49596
|
+
_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.",
|
|
49597
|
+
aiSpecific: true,
|
|
49598
|
+
_v7Verdict: "USEFUL",
|
|
49599
|
+
_v7Lift: 99999,
|
|
49600
|
+
_v7Recall: 0,
|
|
49601
|
+
_v7FpRate: 0,
|
|
49602
|
+
_v7Precision: 1,
|
|
49603
|
+
_v8Verdict: "DORMANT",
|
|
49604
|
+
_v8Lift: 1,
|
|
49605
|
+
defaultOff: false
|
|
47903
49606
|
},
|
|
47904
|
-
"
|
|
47905
|
-
recall:
|
|
49607
|
+
"security/hardcoded-secret": {
|
|
49608
|
+
recall: 14e-4,
|
|
49609
|
+
fpRate: 6e-4,
|
|
49610
|
+
ratio: 1269.08,
|
|
49611
|
+
precision: 0.735,
|
|
49612
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
49613
|
+
verdict: "USEFUL",
|
|
49614
|
+
_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).",
|
|
49615
|
+
aiSpecific: true,
|
|
49616
|
+
_v7Verdict: "USEFUL",
|
|
49617
|
+
_v7Lift: 916.92,
|
|
49618
|
+
_v7Recall: 13e-4,
|
|
49619
|
+
_v7FpRate: 8e-4,
|
|
49620
|
+
_v7Precision: 0.6899,
|
|
49621
|
+
_v8Verdict: "USEFUL",
|
|
49622
|
+
_v8Lift: 7935.57
|
|
49623
|
+
},
|
|
49624
|
+
"security/localstorage-token": {
|
|
49625
|
+
recall: 1e-4,
|
|
47906
49626
|
fpRate: 0,
|
|
47907
|
-
ratio:
|
|
47908
|
-
precision:
|
|
47909
|
-
lastCalibratedAt: "2026-
|
|
49627
|
+
ratio: 99999,
|
|
49628
|
+
precision: 1,
|
|
49629
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
47910
49630
|
verdict: "USEFUL",
|
|
47911
|
-
_calibrationNote: "
|
|
47912
|
-
aiSpecific:
|
|
49631
|
+
_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).",
|
|
49632
|
+
aiSpecific: false,
|
|
49633
|
+
_v7Verdict: "DORMANT",
|
|
49634
|
+
_v7Lift: 1,
|
|
49635
|
+
_v7Recall: 0,
|
|
49636
|
+
_v7FpRate: 0,
|
|
49637
|
+
_v7Precision: 0,
|
|
49638
|
+
_v8Verdict: "USEFUL",
|
|
49639
|
+
_v8Lift: 99999
|
|
47913
49640
|
},
|
|
47914
|
-
"
|
|
47915
|
-
recall:
|
|
47916
|
-
fpRate:
|
|
47917
|
-
ratio:
|
|
47918
|
-
precision:
|
|
47919
|
-
lastCalibratedAt: "2026-
|
|
49641
|
+
"security/missing-auth-check": {
|
|
49642
|
+
recall: 5e-4,
|
|
49643
|
+
fpRate: 0,
|
|
49644
|
+
ratio: 99999,
|
|
49645
|
+
precision: 1,
|
|
49646
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
47920
49647
|
verdict: "USEFUL",
|
|
47921
|
-
_calibrationNote: "
|
|
47922
|
-
aiSpecific:
|
|
49648
|
+
_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).",
|
|
49649
|
+
aiSpecific: false,
|
|
49650
|
+
_v7Verdict: "DORMANT",
|
|
49651
|
+
_v7Lift: 1,
|
|
49652
|
+
_v7Recall: 0,
|
|
49653
|
+
_v7FpRate: 0,
|
|
49654
|
+
_v7Precision: 0,
|
|
49655
|
+
_v8Verdict: "USEFUL",
|
|
49656
|
+
_v8Lift: 99999
|
|
47923
49657
|
},
|
|
47924
|
-
"
|
|
47925
|
-
recall:
|
|
47926
|
-
fpRate:
|
|
47927
|
-
ratio:
|
|
47928
|
-
precision: 0.
|
|
47929
|
-
lastCalibratedAt: "2026-
|
|
49658
|
+
"security/public-admin-route": {
|
|
49659
|
+
recall: 38e-4,
|
|
49660
|
+
fpRate: 38e-4,
|
|
49661
|
+
ratio: 142.2,
|
|
49662
|
+
precision: 0.5376,
|
|
49663
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
47930
49664
|
verdict: "USEFUL",
|
|
47931
|
-
_calibrationNote: "
|
|
47932
|
-
aiSpecific:
|
|
49665
|
+
_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).",
|
|
49666
|
+
aiSpecific: false,
|
|
49667
|
+
_v7Verdict: "DORMANT",
|
|
49668
|
+
_v7Lift: 1,
|
|
49669
|
+
_v7Recall: 0,
|
|
49670
|
+
_v7FpRate: 0,
|
|
49671
|
+
_v7Precision: 0,
|
|
49672
|
+
_v8Verdict: "USEFUL",
|
|
49673
|
+
_v8Lift: 38.74
|
|
47933
49674
|
},
|
|
47934
|
-
"
|
|
47935
|
-
recall:
|
|
47936
|
-
fpRate:
|
|
47937
|
-
ratio:
|
|
47938
|
-
precision: 0.
|
|
47939
|
-
lastCalibratedAt: "2026-
|
|
49675
|
+
"security/sql-construction": {
|
|
49676
|
+
recall: 32e-4,
|
|
49677
|
+
fpRate: 15e-4,
|
|
49678
|
+
ratio: 485.42,
|
|
49679
|
+
precision: 0.7183,
|
|
49680
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
47940
49681
|
verdict: "USEFUL",
|
|
47941
|
-
_calibrationNote: "
|
|
47942
|
-
aiSpecific: true
|
|
49682
|
+
_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).",
|
|
49683
|
+
aiSpecific: true,
|
|
49684
|
+
_v7Verdict: "USEFUL",
|
|
49685
|
+
_v7Lift: 370.52,
|
|
49686
|
+
_v7Recall: 3e-3,
|
|
49687
|
+
_v7FpRate: 18e-4,
|
|
49688
|
+
_v7Precision: 0.6788,
|
|
49689
|
+
_v8Verdict: "USEFUL",
|
|
49690
|
+
_v8Lift: 1608.86
|
|
47943
49691
|
},
|
|
47944
|
-
"
|
|
47945
|
-
recall:
|
|
49692
|
+
"security/target-blank-no-noopener": {
|
|
49693
|
+
recall: 4e-4,
|
|
47946
49694
|
fpRate: 0,
|
|
47947
|
-
ratio:
|
|
47948
|
-
precision: 0,
|
|
47949
|
-
lastCalibratedAt: "2026-
|
|
47950
|
-
verdict: "
|
|
47951
|
-
|
|
47952
|
-
|
|
47953
|
-
|
|
49695
|
+
ratio: 26141.63,
|
|
49696
|
+
precision: 0.9333,
|
|
49697
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
49698
|
+
verdict: "USEFUL",
|
|
49699
|
+
_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).",
|
|
49700
|
+
aiSpecific: false,
|
|
49701
|
+
_v7Verdict: "DORMANT",
|
|
49702
|
+
_v7Lift: 1,
|
|
49703
|
+
_v7Recall: 0,
|
|
49704
|
+
_v7FpRate: 0,
|
|
49705
|
+
_v7Precision: 0,
|
|
49706
|
+
_v8Verdict: "USEFUL",
|
|
49707
|
+
_v8Lift: 7121.02
|
|
47954
49708
|
},
|
|
47955
|
-
"
|
|
47956
|
-
recall:
|
|
49709
|
+
"security/unsafe-html-render": {
|
|
49710
|
+
recall: 13e-4,
|
|
49711
|
+
fpRate: 11e-4,
|
|
49712
|
+
ratio: 513.12,
|
|
49713
|
+
precision: 0.574,
|
|
49714
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
49715
|
+
verdict: "USEFUL",
|
|
49716
|
+
_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).",
|
|
49717
|
+
aiSpecific: false,
|
|
49718
|
+
_v7Verdict: "USEFUL",
|
|
49719
|
+
_v7Lift: 757.74,
|
|
49720
|
+
_v7Recall: 13e-4,
|
|
49721
|
+
_v7FpRate: 9e-4,
|
|
49722
|
+
_v7Precision: 0.661,
|
|
49723
|
+
_v8Verdict: "OK",
|
|
49724
|
+
_v8Lift: 201.44
|
|
49725
|
+
},
|
|
49726
|
+
"test/duplicate-setup": {
|
|
49727
|
+
recall: 1e-4,
|
|
47957
49728
|
fpRate: 0,
|
|
47958
|
-
ratio:
|
|
47959
|
-
precision: 0,
|
|
47960
|
-
lastCalibratedAt: "2026-
|
|
47961
|
-
verdict: "
|
|
47962
|
-
|
|
47963
|
-
|
|
47964
|
-
|
|
49729
|
+
ratio: 51016.19,
|
|
49730
|
+
precision: 0.8095,
|
|
49731
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
49732
|
+
verdict: "USEFUL",
|
|
49733
|
+
_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).",
|
|
49734
|
+
aiSpecific: true,
|
|
49735
|
+
_v7Verdict: "USEFUL",
|
|
49736
|
+
_v7Lift: 50348.67,
|
|
49737
|
+
_v7Recall: 1e-4,
|
|
49738
|
+
_v7FpRate: 0,
|
|
49739
|
+
_v7Precision: 0.8235,
|
|
49740
|
+
_v8Verdict: "USEFUL",
|
|
49741
|
+
_v8Lift: 51500.25
|
|
47965
49742
|
},
|
|
47966
|
-
"
|
|
49743
|
+
"test/fake-placeholder": {
|
|
49744
|
+
recall: 51e-4,
|
|
49745
|
+
fpRate: 15e-4,
|
|
49746
|
+
ratio: 547.47,
|
|
49747
|
+
precision: 0.8014,
|
|
49748
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
49749
|
+
verdict: "USEFUL",
|
|
49750
|
+
_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).",
|
|
49751
|
+
aiSpecific: true,
|
|
49752
|
+
_v7Verdict: "USEFUL",
|
|
49753
|
+
_v7Lift: 418.76,
|
|
49754
|
+
_v7Recall: 53e-4,
|
|
49755
|
+
_v7FpRate: 19e-4,
|
|
49756
|
+
_v7Precision: 0.7854,
|
|
49757
|
+
_v8Verdict: "USEFUL",
|
|
49758
|
+
_v8Lift: 2477.4
|
|
49759
|
+
},
|
|
49760
|
+
"test/missing-edge-case": {
|
|
47967
49761
|
recall: 0,
|
|
47968
49762
|
fpRate: 0,
|
|
47969
49763
|
ratio: 0,
|
|
47970
49764
|
precision: 0,
|
|
47971
|
-
lastCalibratedAt: "2026-
|
|
49765
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
47972
49766
|
verdict: "DORMANT",
|
|
47973
|
-
|
|
47974
|
-
|
|
47975
|
-
|
|
49767
|
+
_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.",
|
|
49768
|
+
aiSpecific: true,
|
|
49769
|
+
_v7Verdict: "DORMANT",
|
|
49770
|
+
_v7Lift: 0,
|
|
49771
|
+
_v7Recall: 0,
|
|
49772
|
+
_v7FpRate: 0,
|
|
49773
|
+
_v7Precision: 0,
|
|
49774
|
+
_v8Verdict: "DORMANT",
|
|
49775
|
+
_v8Lift: 1,
|
|
49776
|
+
defaultOff: true
|
|
47976
49777
|
},
|
|
47977
|
-
"
|
|
49778
|
+
"test/weak-assertion": {
|
|
49779
|
+
recall: 0.0417,
|
|
49780
|
+
fpRate: 67e-4,
|
|
49781
|
+
ratio: 131.62,
|
|
49782
|
+
precision: 0.8793,
|
|
49783
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
49784
|
+
verdict: "USEFUL",
|
|
49785
|
+
_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).",
|
|
49786
|
+
aiSpecific: true,
|
|
49787
|
+
_v7Verdict: "USEFUL",
|
|
49788
|
+
_v7Lift: 99.9,
|
|
49789
|
+
_v7Recall: 0.0418,
|
|
49790
|
+
_v7FpRate: 86e-4,
|
|
49791
|
+
_v7Precision: 0.8622,
|
|
49792
|
+
_v8Verdict: "USEFUL",
|
|
49793
|
+
_v8Lift: 651.94
|
|
49794
|
+
},
|
|
49795
|
+
"ts/enum-vs-as-const": {
|
|
47978
49796
|
recall: 0,
|
|
47979
49797
|
fpRate: 0,
|
|
47980
|
-
ratio:
|
|
49798
|
+
ratio: 1,
|
|
47981
49799
|
precision: 0,
|
|
47982
|
-
lastCalibratedAt: "2026-
|
|
49800
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
47983
49801
|
verdict: "DORMANT",
|
|
47984
|
-
|
|
47985
|
-
|
|
47986
|
-
|
|
49802
|
+
_calibrationNote: "v0.19: new rule (Uses `enum` \u2014 modern TS prefers `as const`). Not yet calibrated. Scheduled for v9 calibration.",
|
|
49803
|
+
aiSpecific: true,
|
|
49804
|
+
_v7Verdict: "DORMANT",
|
|
49805
|
+
_v7Lift: 1,
|
|
49806
|
+
_v7Recall: 0,
|
|
49807
|
+
_v7FpRate: 0,
|
|
49808
|
+
_v7Precision: 0,
|
|
49809
|
+
_v8Verdict: "DORMANT",
|
|
49810
|
+
_v8Lift: 1,
|
|
49811
|
+
defaultOff: true
|
|
47987
49812
|
},
|
|
47988
|
-
"
|
|
49813
|
+
"ts/excessive-type-assertion": {
|
|
47989
49814
|
recall: 0,
|
|
47990
49815
|
fpRate: 0,
|
|
47991
|
-
ratio:
|
|
49816
|
+
ratio: 1,
|
|
47992
49817
|
precision: 0,
|
|
47993
|
-
lastCalibratedAt: "2026-
|
|
49818
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
47994
49819
|
verdict: "DORMANT",
|
|
47995
|
-
|
|
47996
|
-
|
|
47997
|
-
|
|
49820
|
+
_calibrationNote: "v0.19: new rule (Function with >3 `as` assertions \u2014 AI fighting the type system). Not yet calibrated. Scheduled for v9 calibration.",
|
|
49821
|
+
aiSpecific: true,
|
|
49822
|
+
_v7Verdict: "DORMANT",
|
|
49823
|
+
_v7Lift: 1,
|
|
49824
|
+
_v7Recall: 0,
|
|
49825
|
+
_v7FpRate: 0,
|
|
49826
|
+
_v7Precision: 0,
|
|
49827
|
+
_v8Verdict: "DORMANT",
|
|
49828
|
+
_v8Lift: 1,
|
|
49829
|
+
defaultOff: true
|
|
47998
49830
|
},
|
|
47999
|
-
"
|
|
49831
|
+
"ts/import-type-misuse": {
|
|
48000
49832
|
recall: 0,
|
|
48001
49833
|
fpRate: 0,
|
|
48002
|
-
ratio:
|
|
49834
|
+
ratio: 1,
|
|
48003
49835
|
precision: 0,
|
|
48004
|
-
lastCalibratedAt: "2026-
|
|
49836
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
48005
49837
|
verdict: "DORMANT",
|
|
48006
|
-
|
|
48007
|
-
|
|
48008
|
-
|
|
49838
|
+
_calibrationNote: "v0.19: new rule (Inline `import { type X }` \u2014 prefer separate `import type`). Not yet calibrated. Scheduled for v9 calibration.",
|
|
49839
|
+
aiSpecific: true,
|
|
49840
|
+
_v7Verdict: "DORMANT",
|
|
49841
|
+
_v7Lift: 1,
|
|
49842
|
+
_v7Recall: 0,
|
|
49843
|
+
_v7FpRate: 0,
|
|
49844
|
+
_v7Precision: 0,
|
|
49845
|
+
_v8Verdict: "DORMANT",
|
|
49846
|
+
_v8Lift: 1,
|
|
49847
|
+
defaultOff: true
|
|
48009
49848
|
},
|
|
48010
|
-
"
|
|
49849
|
+
"ts/never-vs-unknown": {
|
|
48011
49850
|
recall: 0,
|
|
48012
49851
|
fpRate: 0,
|
|
48013
|
-
ratio:
|
|
49852
|
+
ratio: 1,
|
|
48014
49853
|
precision: 0,
|
|
48015
|
-
lastCalibratedAt: "2026-
|
|
49854
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
48016
49855
|
verdict: "DORMANT",
|
|
48017
|
-
|
|
48018
|
-
|
|
48019
|
-
|
|
49856
|
+
_calibrationNote: "v0.19: new rule (Return type `never` but body has no throw/loop/exit). Not yet calibrated. Scheduled for v9 calibration.",
|
|
49857
|
+
aiSpecific: true,
|
|
49858
|
+
_v7Verdict: "DORMANT",
|
|
49859
|
+
_v7Lift: 1,
|
|
49860
|
+
_v7Recall: 0,
|
|
49861
|
+
_v7FpRate: 0,
|
|
49862
|
+
_v7Precision: 0,
|
|
49863
|
+
_v8Verdict: "DORMANT",
|
|
49864
|
+
_v8Lift: 1,
|
|
49865
|
+
defaultOff: true
|
|
48020
49866
|
},
|
|
48021
|
-
"
|
|
49867
|
+
"ts/optional-chain-overuse": {
|
|
48022
49868
|
recall: 0,
|
|
48023
49869
|
fpRate: 0,
|
|
48024
|
-
ratio:
|
|
49870
|
+
ratio: 1,
|
|
48025
49871
|
precision: 0,
|
|
48026
|
-
lastCalibratedAt: "2026-
|
|
49872
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
48027
49873
|
verdict: "DORMANT",
|
|
48028
|
-
|
|
48029
|
-
|
|
48030
|
-
|
|
49874
|
+
_calibrationNote: "v0.19: new rule (Optional chain depth >= 5 \u2014 AI chains ?. rather than narrowing). Not yet calibrated. Scheduled for v9 calibration.",
|
|
49875
|
+
aiSpecific: true,
|
|
49876
|
+
_v7Verdict: "DORMANT",
|
|
49877
|
+
_v7Lift: 1,
|
|
49878
|
+
_v7Recall: 0,
|
|
49879
|
+
_v7FpRate: 0,
|
|
49880
|
+
_v7Precision: 0,
|
|
49881
|
+
_v8Verdict: "DORMANT",
|
|
49882
|
+
_v8Lift: 1,
|
|
49883
|
+
defaultOff: true
|
|
48031
49884
|
},
|
|
48032
|
-
"
|
|
49885
|
+
"typo/calc-fontsize": {
|
|
48033
49886
|
recall: 0,
|
|
48034
49887
|
fpRate: 0,
|
|
48035
49888
|
ratio: 0,
|
|
48036
49889
|
precision: 0,
|
|
48037
|
-
lastCalibratedAt: "2026-
|
|
49890
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
48038
49891
|
verdict: "DORMANT",
|
|
48039
|
-
|
|
48040
|
-
|
|
48041
|
-
|
|
49892
|
+
_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.",
|
|
49893
|
+
aiSpecific: false,
|
|
49894
|
+
_v7Verdict: "DORMANT",
|
|
49895
|
+
_v7Lift: 0,
|
|
49896
|
+
_v7Recall: 0,
|
|
49897
|
+
_v7FpRate: 0,
|
|
49898
|
+
_v7Precision: 0,
|
|
49899
|
+
_v8Verdict: "DORMANT",
|
|
49900
|
+
_v8Lift: 1,
|
|
49901
|
+
defaultOff: true
|
|
48042
49902
|
},
|
|
48043
|
-
"
|
|
49903
|
+
"typo/calc-raw-px": {
|
|
48044
49904
|
recall: 0,
|
|
48045
49905
|
fpRate: 0,
|
|
48046
|
-
ratio:
|
|
48047
|
-
precision: 0,
|
|
48048
|
-
lastCalibratedAt: "2026-
|
|
48049
|
-
verdict: "
|
|
48050
|
-
|
|
48051
|
-
|
|
48052
|
-
|
|
49906
|
+
ratio: 210066.67,
|
|
49907
|
+
precision: 0.8333,
|
|
49908
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
49909
|
+
verdict: "USEFUL",
|
|
49910
|
+
_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).",
|
|
49911
|
+
aiSpecific: false,
|
|
49912
|
+
_v7Verdict: "USEFUL",
|
|
49913
|
+
_v7Lift: 137559.75,
|
|
49914
|
+
_v7Recall: 0,
|
|
49915
|
+
_v7FpRate: 0,
|
|
49916
|
+
_v7Precision: 0.75,
|
|
49917
|
+
_v8Verdict: "USEFUL",
|
|
49918
|
+
_v8Lift: 99999
|
|
48053
49919
|
},
|
|
48054
|
-
"
|
|
49920
|
+
"typo/clamp-offscale": {
|
|
48055
49921
|
recall: 0,
|
|
48056
49922
|
fpRate: 0,
|
|
48057
49923
|
ratio: 0,
|
|
48058
49924
|
precision: 0,
|
|
48059
|
-
lastCalibratedAt: "2026-
|
|
49925
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
48060
49926
|
verdict: "DORMANT",
|
|
48061
|
-
|
|
48062
|
-
|
|
48063
|
-
|
|
49927
|
+
_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.",
|
|
49928
|
+
aiSpecific: false,
|
|
49929
|
+
_v7Verdict: "DORMANT",
|
|
49930
|
+
_v7Lift: 0,
|
|
49931
|
+
_v7Recall: 0,
|
|
49932
|
+
_v7FpRate: 0,
|
|
49933
|
+
_v7Precision: 0,
|
|
49934
|
+
_v8Verdict: "DORMANT",
|
|
49935
|
+
_v8Lift: 1,
|
|
49936
|
+
defaultOff: true
|
|
48064
49937
|
},
|
|
48065
|
-
"
|
|
49938
|
+
"typo/math-button-label-uniformity": {
|
|
49939
|
+
recall: 1e-4,
|
|
49940
|
+
fpRate: 1e-4,
|
|
49941
|
+
ratio: 6894.19,
|
|
49942
|
+
precision: 0.629,
|
|
49943
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
49944
|
+
verdict: "USEFUL",
|
|
49945
|
+
_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).",
|
|
49946
|
+
aiSpecific: false,
|
|
49947
|
+
_v7Verdict: "USEFUL",
|
|
49948
|
+
_v7Lift: 5571.66,
|
|
49949
|
+
_v7Recall: 2e-4,
|
|
49950
|
+
_v7FpRate: 1e-4,
|
|
49951
|
+
_v7Precision: 0.6379,
|
|
49952
|
+
_v8Verdict: "USEFUL",
|
|
49953
|
+
_v8Lift: 17166.75
|
|
49954
|
+
},
|
|
49955
|
+
"typo/math-cta-vocabulary": {
|
|
48066
49956
|
recall: 0,
|
|
48067
49957
|
fpRate: 0,
|
|
48068
49958
|
ratio: 0,
|
|
48069
49959
|
precision: 0,
|
|
48070
|
-
lastCalibratedAt: "2026-
|
|
49960
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
48071
49961
|
verdict: "DORMANT",
|
|
48072
|
-
|
|
48073
|
-
|
|
48074
|
-
|
|
49962
|
+
_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.",
|
|
49963
|
+
aiSpecific: true,
|
|
49964
|
+
_v7Verdict: "DORMANT",
|
|
49965
|
+
_v7Lift: 0,
|
|
49966
|
+
_v7Recall: 0,
|
|
49967
|
+
_v7FpRate: 0,
|
|
49968
|
+
_v7Precision: 0,
|
|
49969
|
+
_v8Verdict: "DORMANT",
|
|
49970
|
+
_v8Lift: 1,
|
|
49971
|
+
defaultOff: true
|
|
48075
49972
|
},
|
|
48076
|
-
"
|
|
48077
|
-
recall:
|
|
49973
|
+
"typo/placeholder-text": {
|
|
49974
|
+
recall: 1e-4,
|
|
48078
49975
|
fpRate: 0,
|
|
48079
|
-
ratio:
|
|
48080
|
-
precision: 0,
|
|
48081
|
-
lastCalibratedAt: "2026-
|
|
48082
|
-
verdict: "
|
|
48083
|
-
|
|
48084
|
-
|
|
48085
|
-
|
|
49976
|
+
ratio: 17330.5,
|
|
49977
|
+
precision: 0.6875,
|
|
49978
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
49979
|
+
verdict: "USEFUL",
|
|
49980
|
+
_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).",
|
|
49981
|
+
aiSpecific: false,
|
|
49982
|
+
_v7Verdict: "DORMANT",
|
|
49983
|
+
_v7Lift: 1,
|
|
49984
|
+
_v7Recall: 0,
|
|
49985
|
+
_v7FpRate: 0,
|
|
49986
|
+
_v7Precision: 0,
|
|
49987
|
+
_v8Verdict: "USEFUL",
|
|
49988
|
+
_v8Lift: 4720.86
|
|
48086
49989
|
},
|
|
48087
|
-
"
|
|
49990
|
+
"visual/arbitrary-escape": {
|
|
49991
|
+
recall: 26e-4,
|
|
49992
|
+
fpRate: 7e-4,
|
|
49993
|
+
ratio: 1219.67,
|
|
49994
|
+
precision: 0.8177,
|
|
49995
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
49996
|
+
verdict: "USEFUL",
|
|
49997
|
+
_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).",
|
|
49998
|
+
aiSpecific: true,
|
|
49999
|
+
_v7Verdict: "USEFUL",
|
|
50000
|
+
_v7Lift: 846.78,
|
|
50001
|
+
_v7Recall: 25e-4,
|
|
50002
|
+
_v7FpRate: 9e-4,
|
|
50003
|
+
_v7Precision: 0.7802,
|
|
50004
|
+
_v8Verdict: "USEFUL",
|
|
50005
|
+
_v8Lift: 99999
|
|
50006
|
+
},
|
|
50007
|
+
"visual/clamp-soup": {
|
|
48088
50008
|
recall: 0,
|
|
48089
50009
|
fpRate: 0,
|
|
48090
50010
|
ratio: 0,
|
|
48091
50011
|
precision: 0,
|
|
48092
|
-
lastCalibratedAt: "2026-
|
|
50012
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
48093
50013
|
verdict: "DORMANT",
|
|
48094
|
-
|
|
48095
|
-
|
|
48096
|
-
|
|
50014
|
+
_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.",
|
|
50015
|
+
aiSpecific: true,
|
|
50016
|
+
_v7Verdict: "DORMANT",
|
|
50017
|
+
_v7Lift: 0,
|
|
50018
|
+
_v7Recall: 0,
|
|
50019
|
+
_v7FpRate: 0,
|
|
50020
|
+
_v7Precision: 0,
|
|
50021
|
+
_v8Verdict: "DORMANT",
|
|
50022
|
+
_v8Lift: 1,
|
|
50023
|
+
defaultOff: true
|
|
48097
50024
|
},
|
|
48098
|
-
"
|
|
50025
|
+
"visual/generic-centering": {
|
|
48099
50026
|
recall: 0,
|
|
48100
50027
|
fpRate: 0,
|
|
48101
50028
|
ratio: 0,
|
|
48102
50029
|
precision: 0,
|
|
48103
|
-
lastCalibratedAt: "2026-
|
|
50030
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
48104
50031
|
verdict: "DORMANT",
|
|
48105
|
-
|
|
48106
|
-
|
|
48107
|
-
|
|
50032
|
+
_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.",
|
|
50033
|
+
aiSpecific: true,
|
|
50034
|
+
_v7Verdict: "DORMANT",
|
|
50035
|
+
_v7Lift: 0,
|
|
50036
|
+
_v7Recall: 0,
|
|
50037
|
+
_v7FpRate: 0,
|
|
50038
|
+
_v7Precision: 0,
|
|
50039
|
+
_v8Verdict: "DORMANT",
|
|
50040
|
+
_v8Lift: 1,
|
|
50041
|
+
defaultOff: true
|
|
48108
50042
|
},
|
|
48109
|
-
"
|
|
48110
|
-
recall: 0,
|
|
50043
|
+
"visual/inline-style-dominance": {
|
|
50044
|
+
recall: 0.0103,
|
|
50045
|
+
fpRate: 52e-4,
|
|
50046
|
+
ratio: 134.59,
|
|
50047
|
+
precision: 0.6983,
|
|
50048
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
50049
|
+
verdict: "USEFUL",
|
|
50050
|
+
_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).",
|
|
50051
|
+
aiSpecific: false,
|
|
50052
|
+
_v7Verdict: "USEFUL",
|
|
50053
|
+
_v7Lift: 98.17,
|
|
50054
|
+
_v7Recall: 97e-4,
|
|
50055
|
+
_v7FpRate: 67e-4,
|
|
50056
|
+
_v7Precision: 0.6535,
|
|
50057
|
+
_v8Verdict: "USEFUL",
|
|
50058
|
+
_v8Lift: 704.71
|
|
50059
|
+
},
|
|
50060
|
+
"visual/math-color-cluster": {
|
|
50061
|
+
recall: 2e-4,
|
|
48111
50062
|
fpRate: 0,
|
|
48112
|
-
ratio:
|
|
48113
|
-
precision: 0,
|
|
48114
|
-
lastCalibratedAt: "2026-
|
|
48115
|
-
verdict: "
|
|
48116
|
-
|
|
48117
|
-
|
|
48118
|
-
|
|
50063
|
+
ratio: 46814.86,
|
|
50064
|
+
precision: 0.9286,
|
|
50065
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
50066
|
+
verdict: "USEFUL",
|
|
50067
|
+
_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).",
|
|
50068
|
+
aiSpecific: true,
|
|
50069
|
+
_v7Verdict: "USEFUL",
|
|
50070
|
+
_v7Lift: 33771.28,
|
|
50071
|
+
_v7Recall: 2e-4,
|
|
50072
|
+
_v7FpRate: 0,
|
|
50073
|
+
_v7Precision: 0.9206,
|
|
50074
|
+
_v8Verdict: "USEFUL",
|
|
50075
|
+
_v8Lift: 99999
|
|
48119
50076
|
},
|
|
48120
|
-
"
|
|
50077
|
+
"visual/math-default-font": {
|
|
50078
|
+
recall: 16e-4,
|
|
50079
|
+
fpRate: 3e-4,
|
|
50080
|
+
ratio: 3035.16,
|
|
50081
|
+
precision: 0.8669,
|
|
50082
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
50083
|
+
verdict: "USEFUL",
|
|
50084
|
+
_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).",
|
|
50085
|
+
aiSpecific: true,
|
|
50086
|
+
_v7Verdict: "USEFUL",
|
|
50087
|
+
_v7Lift: 2105.64,
|
|
50088
|
+
_v7Recall: 13e-4,
|
|
50089
|
+
_v7FpRate: 4e-4,
|
|
50090
|
+
_v7Precision: 0.8151,
|
|
50091
|
+
_v8Verdict: "USEFUL",
|
|
50092
|
+
_v8Lift: 68229.63
|
|
50093
|
+
},
|
|
50094
|
+
"visual/math-font-entropy": {
|
|
50095
|
+
recall: 52e-4,
|
|
50096
|
+
fpRate: 1e-3,
|
|
50097
|
+
ratio: 869.95,
|
|
50098
|
+
precision: 0.8593,
|
|
50099
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
50100
|
+
verdict: "USEFUL",
|
|
50101
|
+
_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).",
|
|
50102
|
+
aiSpecific: true,
|
|
50103
|
+
_v7Verdict: "USEFUL",
|
|
50104
|
+
_v7Lift: 600.09,
|
|
50105
|
+
_v7Recall: 45e-4,
|
|
50106
|
+
_v7FpRate: 14e-4,
|
|
50107
|
+
_v7Precision: 0.8114,
|
|
50108
|
+
_v8Verdict: "USEFUL",
|
|
50109
|
+
_v8Lift: 68516.08
|
|
50110
|
+
},
|
|
50111
|
+
"visual/math-gradient-hue-rotation": {
|
|
48121
50112
|
recall: 0,
|
|
48122
50113
|
fpRate: 0,
|
|
48123
50114
|
ratio: 0,
|
|
48124
50115
|
precision: 0,
|
|
48125
|
-
lastCalibratedAt: "2026-
|
|
50116
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
48126
50117
|
verdict: "DORMANT",
|
|
48127
|
-
|
|
48128
|
-
|
|
48129
|
-
|
|
50118
|
+
_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.",
|
|
50119
|
+
aiSpecific: true,
|
|
50120
|
+
_v7Verdict: "DORMANT",
|
|
50121
|
+
_v7Lift: 0,
|
|
50122
|
+
_v7Recall: 0,
|
|
50123
|
+
_v7FpRate: 0,
|
|
50124
|
+
_v7Precision: 0,
|
|
50125
|
+
_v8Verdict: "DORMANT",
|
|
50126
|
+
_v8Lift: 1,
|
|
50127
|
+
defaultOff: true
|
|
48130
50128
|
},
|
|
48131
|
-
"
|
|
48132
|
-
recall:
|
|
50129
|
+
"visual/math-rounded-entropy": {
|
|
50130
|
+
recall: 38e-4,
|
|
50131
|
+
fpRate: 2e-4,
|
|
50132
|
+
ratio: 3785.45,
|
|
50133
|
+
precision: 0.9461,
|
|
50134
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
50135
|
+
verdict: "USEFUL",
|
|
50136
|
+
_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).",
|
|
50137
|
+
aiSpecific: true,
|
|
50138
|
+
_v7Verdict: "USEFUL",
|
|
50139
|
+
_v7Lift: 2762.74,
|
|
50140
|
+
_v7Recall: 37e-4,
|
|
50141
|
+
_v7FpRate: 3e-4,
|
|
50142
|
+
_v7Precision: 0.9339,
|
|
50143
|
+
_v8Verdict: "USEFUL",
|
|
50144
|
+
_v8Lift: 68368.45
|
|
50145
|
+
},
|
|
50146
|
+
"visual/math-spacing-entropy": {
|
|
50147
|
+
recall: 18e-4,
|
|
50148
|
+
fpRate: 4e-4,
|
|
50149
|
+
ratio: 1898.99,
|
|
50150
|
+
precision: 0.8287,
|
|
50151
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
50152
|
+
verdict: "USEFUL",
|
|
50153
|
+
_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).",
|
|
50154
|
+
aiSpecific: true,
|
|
50155
|
+
_v7Verdict: "USEFUL",
|
|
50156
|
+
_v7Lift: 1339.22,
|
|
50157
|
+
_v7Recall: 18e-4,
|
|
50158
|
+
_v7FpRate: 6e-4,
|
|
50159
|
+
_v7Precision: 0.7959,
|
|
50160
|
+
_v8Verdict: "USEFUL",
|
|
50161
|
+
_v8Lift: 68031.19
|
|
50162
|
+
},
|
|
50163
|
+
"visual/naturalness-anomaly": {
|
|
50164
|
+
recall: 0.1729,
|
|
50165
|
+
fpRate: 0.0687,
|
|
50166
|
+
ratio: 10.86,
|
|
50167
|
+
precision: 0.746,
|
|
50168
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
50169
|
+
verdict: "USEFUL",
|
|
50170
|
+
_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).",
|
|
50171
|
+
aiSpecific: true,
|
|
50172
|
+
_v7Verdict: "USEFUL",
|
|
50173
|
+
_v7Lift: 12.5,
|
|
50174
|
+
_v7Recall: 0.1659,
|
|
50175
|
+
_v7FpRate: 0.0621,
|
|
50176
|
+
_v7Precision: 0.7755,
|
|
50177
|
+
_v8Verdict: "USEFUL",
|
|
50178
|
+
_v8Lift: 7.64
|
|
50179
|
+
},
|
|
50180
|
+
"visual/radius-scale-violation": {
|
|
50181
|
+
recall: 4e-4,
|
|
48133
50182
|
fpRate: 0,
|
|
48134
|
-
ratio:
|
|
48135
|
-
precision: 0,
|
|
48136
|
-
lastCalibratedAt: "2026-
|
|
48137
|
-
verdict: "
|
|
48138
|
-
defaultOff:
|
|
48139
|
-
|
|
48140
|
-
|
|
50183
|
+
ratio: 82131.33,
|
|
50184
|
+
precision: 0.9774,
|
|
50185
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
50186
|
+
verdict: "USEFUL",
|
|
50187
|
+
_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.",
|
|
50188
|
+
aiSpecific: false,
|
|
50189
|
+
_v7Verdict: "USEFUL",
|
|
50190
|
+
_v7Lift: 59285.01,
|
|
50191
|
+
_v7Recall: 4e-4,
|
|
50192
|
+
_v7FpRate: 0,
|
|
50193
|
+
_v7Precision: 0.9697,
|
|
50194
|
+
_v8Verdict: "USEFUL",
|
|
50195
|
+
_v8Lift: 99999,
|
|
50196
|
+
defaultOff: false
|
|
48141
50197
|
},
|
|
48142
|
-
"
|
|
50198
|
+
"visual/spacing-scale-violation": {
|
|
50199
|
+
recall: 86e-4,
|
|
50200
|
+
fpRate: 28e-4,
|
|
50201
|
+
ratio: 273.97,
|
|
50202
|
+
precision: 0.7792,
|
|
50203
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
50204
|
+
verdict: "USEFUL",
|
|
50205
|
+
_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).",
|
|
50206
|
+
aiSpecific: false,
|
|
50207
|
+
_v7Verdict: "USEFUL",
|
|
50208
|
+
_v7Lift: 187.83,
|
|
50209
|
+
_v7Recall: 84e-4,
|
|
50210
|
+
_v7FpRate: 39e-4,
|
|
50211
|
+
_v7Precision: 0.7342,
|
|
50212
|
+
_v8Verdict: "USEFUL",
|
|
50213
|
+
_v8Lift: 99999
|
|
50214
|
+
},
|
|
50215
|
+
"wcag/dragging-movements": {
|
|
48143
50216
|
recall: 0,
|
|
48144
50217
|
fpRate: 0,
|
|
48145
|
-
ratio:
|
|
48146
|
-
precision: 0,
|
|
48147
|
-
lastCalibratedAt: "2026-
|
|
48148
|
-
verdict: "
|
|
48149
|
-
|
|
48150
|
-
|
|
48151
|
-
|
|
50218
|
+
ratio: 33610.67,
|
|
50219
|
+
precision: 0.4,
|
|
50220
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
50221
|
+
verdict: "OK",
|
|
50222
|
+
_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).",
|
|
50223
|
+
aiSpecific: false,
|
|
50224
|
+
_v7Verdict: "OK",
|
|
50225
|
+
_v7Lift: 24455.07,
|
|
50226
|
+
_v7Recall: 0,
|
|
50227
|
+
_v7FpRate: 0,
|
|
50228
|
+
_v7Precision: 0.4,
|
|
50229
|
+
_v8Verdict: "DORMANT",
|
|
50230
|
+
_v8Lift: 1
|
|
48152
50231
|
},
|
|
48153
|
-
"
|
|
50232
|
+
"wcag/focus-appearance": {
|
|
50233
|
+
recall: 28e-4,
|
|
50234
|
+
fpRate: 1e-4,
|
|
50235
|
+
ratio: 8397.24,
|
|
50236
|
+
precision: 0.966,
|
|
50237
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
50238
|
+
verdict: "USEFUL",
|
|
50239
|
+
_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).",
|
|
50240
|
+
aiSpecific: false,
|
|
50241
|
+
_v7Verdict: "USEFUL",
|
|
50242
|
+
_v7Lift: 7353.82,
|
|
50243
|
+
_v7Recall: 26e-4,
|
|
50244
|
+
_v7FpRate: 1e-4,
|
|
50245
|
+
_v7Precision: 0.9623,
|
|
50246
|
+
_v8Verdict: "USEFUL",
|
|
50247
|
+
_v8Lift: 13418.41
|
|
50248
|
+
},
|
|
50249
|
+
"wcag/focus-obscured": {
|
|
50250
|
+
recall: 33e-4,
|
|
50251
|
+
fpRate: 7e-4,
|
|
50252
|
+
ratio: 1214.21,
|
|
50253
|
+
precision: 0.8478,
|
|
50254
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
50255
|
+
verdict: "USEFUL",
|
|
50256
|
+
_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).",
|
|
50257
|
+
aiSpecific: false,
|
|
50258
|
+
_v7Verdict: "USEFUL",
|
|
50259
|
+
_v7Lift: 859.38,
|
|
50260
|
+
_v7Recall: 34e-4,
|
|
50261
|
+
_v7FpRate: 1e-3,
|
|
50262
|
+
_v7Precision: 0.82,
|
|
50263
|
+
_v8Verdict: "USEFUL",
|
|
50264
|
+
_v8Lift: 68293.81
|
|
50265
|
+
},
|
|
50266
|
+
"wcag/missing-alt": {
|
|
50267
|
+
recall: 11e-4,
|
|
50268
|
+
fpRate: 7e-4,
|
|
50269
|
+
ratio: 935.33,
|
|
50270
|
+
precision: 0.6456,
|
|
50271
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
50272
|
+
verdict: "USEFUL",
|
|
50273
|
+
_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).",
|
|
50274
|
+
aiSpecific: false,
|
|
50275
|
+
_v7Verdict: "DORMANT",
|
|
50276
|
+
_v7Lift: 1,
|
|
50277
|
+
_v7Recall: 0,
|
|
50278
|
+
_v7FpRate: 0,
|
|
50279
|
+
_v7Precision: 0,
|
|
50280
|
+
_v8Verdict: "USEFUL",
|
|
50281
|
+
_v8Lift: 254.79
|
|
50282
|
+
},
|
|
50283
|
+
"wcag/target-size": {
|
|
48154
50284
|
recall: 0,
|
|
48155
50285
|
fpRate: 0,
|
|
48156
50286
|
ratio: 0,
|
|
48157
50287
|
precision: 0,
|
|
48158
|
-
lastCalibratedAt: "2026-
|
|
50288
|
+
lastCalibratedAt: "2026-07-01T00:00:00Z",
|
|
48159
50289
|
verdict: "DORMANT",
|
|
48160
|
-
|
|
48161
|
-
|
|
48162
|
-
|
|
50290
|
+
_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.",
|
|
50291
|
+
aiSpecific: false,
|
|
50292
|
+
_v7Verdict: "DORMANT",
|
|
50293
|
+
_v7Lift: 0,
|
|
50294
|
+
_v7Recall: 0,
|
|
50295
|
+
_v7FpRate: 0,
|
|
50296
|
+
_v7Precision: 0,
|
|
50297
|
+
_v8Verdict: "DORMANT",
|
|
50298
|
+
_v8Lift: 1,
|
|
50299
|
+
defaultOff: true
|
|
48163
50300
|
}
|
|
48164
50301
|
};
|
|
48165
50302
|
}
|
|
@@ -48229,7 +50366,6 @@ async function scanFile(filePath, config, registry, cwd = process.cwd()) {
|
|
|
48229
50366
|
".kt",
|
|
48230
50367
|
".kts",
|
|
48231
50368
|
".dart",
|
|
48232
|
-
".rs",
|
|
48233
50369
|
".cpp",
|
|
48234
50370
|
".cc",
|
|
48235
50371
|
".cxx",
|
|
@@ -55058,7 +57194,24 @@ var RULE_HINTS = {
|
|
|
55058
57194
|
"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.",
|
|
55059
57195
|
"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.",
|
|
55060
57196
|
"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.",
|
|
55061
|
-
"docs/broken-link": "Create the file or fix the link target. On a public docs site, broken links erode trust more than stale copy."
|
|
57197
|
+
"docs/broken-link": "Create the file or fix the link target. On a public docs site, broken links erode trust more than stale copy.",
|
|
57198
|
+
// v0.18.9 — Rust-specific rules (tree-sitter-backed)
|
|
57199
|
+
"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.",
|
|
57200
|
+
"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.",
|
|
57201
|
+
"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.",
|
|
57202
|
+
"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.',
|
|
57203
|
+
// v0.19.0 — TypeScript-specific rules
|
|
57204
|
+
"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.",
|
|
57205
|
+
"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.",
|
|
57206
|
+
"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.",
|
|
57207
|
+
"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.",
|
|
57208
|
+
"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.",
|
|
57209
|
+
// v0.19.0 — Go-specific rules
|
|
57210
|
+
"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.',
|
|
57211
|
+
"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).',
|
|
57212
|
+
"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.",
|
|
57213
|
+
// v0.19.0 — Duplication detector
|
|
57214
|
+
"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."
|
|
55062
57215
|
};
|
|
55063
57216
|
|
|
55064
57217
|
// src/cli/commands/explain.ts
|