slopbrick 0.18.5 → 0.18.9

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.
@@ -1,9 +1,14 @@
1
1
  const __importMetaUrl = require("url").pathToFileURL(__filename).href;
2
2
  "use strict";
3
+ var __create = Object.create;
3
4
  var __defProp = Object.defineProperty;
4
5
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
6
  var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __getProtoOf = Object.getPrototypeOf;
6
8
  var __hasOwnProp = Object.prototype.hasOwnProperty;
9
+ var __esm = (fn, res) => function __init() {
10
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
11
+ };
7
12
  var __export = (target, all) => {
8
13
  for (var name in all)
9
14
  __defProp(target, name, { get: all[name], enumerable: true });
@@ -16,8 +21,418 @@ var __copyProps = (to, from, except, desc) => {
16
21
  }
17
22
  return to;
18
23
  };
24
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
25
+ // If the importer is in node compatibility mode or this is not an ESM
26
+ // file that has been converted to a CommonJS file using a Babel-
27
+ // compatible transform (i.e. "__esModule" has not been set), then set
28
+ // "default" to the CommonJS "module.exports" for node compatibility.
29
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
30
+ mod
31
+ ));
19
32
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
20
33
 
34
+ // src/engine/parser-rust.ts
35
+ function getRustParser() {
36
+ if (cachedParser) return { ok: true, parser: cachedParser };
37
+ if (loadError) return { ok: false, error: loadError };
38
+ try {
39
+ rustLanguage = import_tree_sitter_rust.default;
40
+ if (!rustLanguage || typeof rustLanguage !== "object") {
41
+ throw new Error("tree-sitter-rust: language export is missing or malformed");
42
+ }
43
+ const parser = new import_tree_sitter.default();
44
+ parser.setLanguage(rustLanguage);
45
+ cachedParser = parser;
46
+ return { ok: true, parser };
47
+ } catch (err) {
48
+ loadError = err instanceof Error ? err : new Error(String(err));
49
+ return { ok: false, error: loadError };
50
+ }
51
+ }
52
+ function effectiveParser() {
53
+ if (forcedFailure) return { ok: false, error: forcedFailure };
54
+ return getRustParser();
55
+ }
56
+ function parseRust(source) {
57
+ const result = effectiveParser();
58
+ if (!result.ok) return null;
59
+ if (!source || source.trim() === "") return null;
60
+ try {
61
+ const rawTree = result.parser.parse(source);
62
+ if (!rawTree) return null;
63
+ const tree = rawTree;
64
+ if (!tree || !tree.rootNode) return null;
65
+ if (tree.rootNode.type === "ERROR" && tree.rootNode.childCount === 0) {
66
+ return null;
67
+ }
68
+ return tree;
69
+ } catch {
70
+ return null;
71
+ }
72
+ }
73
+ function isRustParserAvailable() {
74
+ const result = getRustParser();
75
+ return result.ok;
76
+ }
77
+ var import_tree_sitter, import_tree_sitter_rust, cachedParser, rustLanguage, loadError, forcedFailure;
78
+ var init_parser_rust = __esm({
79
+ "src/engine/parser-rust.ts"() {
80
+ "use strict";
81
+ import_tree_sitter = __toESM(require("tree-sitter"), 1);
82
+ import_tree_sitter_rust = __toESM(require("tree-sitter-rust"), 1);
83
+ cachedParser = null;
84
+ rustLanguage = null;
85
+ loadError = null;
86
+ forcedFailure = null;
87
+ }
88
+ });
89
+
90
+ // src/engine/visitors/rust.ts
91
+ function parseRustFile(filePath, source, options = {}) {
92
+ const empty = {
93
+ imports: [],
94
+ functions: [],
95
+ structs: [],
96
+ traits: [],
97
+ impls: []
98
+ };
99
+ if (!isRustParserAvailable() || options.forceFallback) {
100
+ return empty;
101
+ }
102
+ const tree = parseRust(source);
103
+ if (!tree) return empty;
104
+ return walkRustTree(tree);
105
+ }
106
+ function walkRustTree(tree) {
107
+ const ctx = { inTestConfig: false };
108
+ const out = {
109
+ imports: [],
110
+ functions: [],
111
+ structs: [],
112
+ traits: [],
113
+ impls: []
114
+ };
115
+ walkChildren(tree.rootNode, ctx, out);
116
+ return out;
117
+ }
118
+ function walkChildren(node, ctx, out) {
119
+ for (let i = 0; i < node.namedChildCount; i++) {
120
+ const child = node.namedChild(i);
121
+ if (!child) continue;
122
+ visitNode(child, ctx, out);
123
+ }
124
+ }
125
+ function visitNode(node, ctx, out) {
126
+ const innerCtx = { ...ctx };
127
+ const attrState = readPrecedingAttributes(node);
128
+ switch (node.type) {
129
+ case "use_declaration": {
130
+ out.imports.push(extractUse(node));
131
+ return;
132
+ }
133
+ case "function_item": {
134
+ const isMethod = isInImplBlock(node);
135
+ out.functions.push(extractFunction(node, attrState, innerCtx.inTestConfig, isMethod));
136
+ walkChildren(getField(node, "body") ?? node, innerCtx, out);
137
+ return;
138
+ }
139
+ case "struct_item": {
140
+ out.structs.push(extractStruct(node, attrState));
141
+ const body = getField(node, "body");
142
+ if (body) walkChildren(body, innerCtx, out);
143
+ return;
144
+ }
145
+ case "trait_item": {
146
+ out.traits.push(extractTrait(node, attrState));
147
+ const body = getField(node, "body");
148
+ if (body) walkChildren(body, innerCtx, out);
149
+ return;
150
+ }
151
+ case "impl_item": {
152
+ const implEntry = extractImpl(node, attrState, innerCtx);
153
+ out.impls.push(implEntry.entry);
154
+ const body = getField(node, "body");
155
+ if (body) walkChildren(body, innerCtx, out);
156
+ return;
157
+ }
158
+ case "mod_item": {
159
+ const modIsTest = innerCtx.inTestConfig || attrState.isTestCfg;
160
+ const modCtx = { ...innerCtx, inTestConfig: modIsTest };
161
+ const body = getField(node, "body");
162
+ if (body) walkChildren(body, modCtx, out);
163
+ return;
164
+ }
165
+ default: {
166
+ for (let i = 0; i < node.namedChildCount; i++) {
167
+ const child = node.namedChild(i);
168
+ if (child) visitNode(child, innerCtx, out);
169
+ }
170
+ }
171
+ }
172
+ }
173
+ function readPrecedingAttributes(node) {
174
+ const state = {
175
+ isTestCfg: false,
176
+ isTest: false,
177
+ isPub: false,
178
+ derives: []
179
+ };
180
+ const parent = node.parent;
181
+ if (!parent) return state;
182
+ for (let i = 0; i < parent.namedChildCount; i++) {
183
+ const sibling = parent.namedChild(i);
184
+ if (!sibling || sibling === node) continue;
185
+ if (sibling.endIndex > node.startIndex) continue;
186
+ if (sibling.type !== "attribute_item") continue;
187
+ decodeAttribute(sibling, state);
188
+ }
189
+ return state;
190
+ }
191
+ function decodeAttribute(attr, state) {
192
+ for (let i = 0; i < attr.namedChildCount; i++) {
193
+ const child = attr.namedChild(i);
194
+ if (!child || child.type !== "attribute") continue;
195
+ const name = firstIdentifier(child);
196
+ if (!name) continue;
197
+ if (name === "cfg") {
198
+ const cfgText = child.text;
199
+ if (/\btest\b/.test(cfgText) && !/\bnot\(test\)/.test(cfgText)) {
200
+ state.isTestCfg = true;
201
+ }
202
+ } else if (name === "test") {
203
+ state.isTest = true;
204
+ } else if (name === "derive") {
205
+ for (let j = 0; j < child.namedChildCount; j++) {
206
+ const inner = child.namedChild(j);
207
+ if (inner) {
208
+ const matches = inner.text.matchAll(/\b([A-Z][A-Za-z0-9_]*)\b/g);
209
+ for (const m of matches) state.derives.push(m[1]);
210
+ }
211
+ }
212
+ }
213
+ }
214
+ }
215
+ function firstIdentifier(node) {
216
+ const text = node.text;
217
+ const idMatch = text.match(/^([a-zA-Z_][a-zA-Z0-9_]*)/);
218
+ return idMatch ? idMatch[1] : null;
219
+ }
220
+ function extractUse(node) {
221
+ const text = node.text;
222
+ const argument = node.namedChild(0);
223
+ const argField = node.childForFieldName("argument");
224
+ const path = argField?.text ?? argument?.text ?? "";
225
+ const names = [];
226
+ let isGlob = false;
227
+ const useListNode = findUseListNode(argument);
228
+ if (useListNode) {
229
+ for (let i = 0; i < useListNode.namedChildCount; i++) {
230
+ const item = useListNode.namedChild(i);
231
+ if (item.type === "use_wildcard") {
232
+ isGlob = true;
233
+ } else if (item.type === "identifier") {
234
+ names.push({ name: item.text });
235
+ } else if (item.type === "use_as_clause") {
236
+ const alias = item.childForFieldName("alias");
237
+ const binding = item.childForFieldName("path");
238
+ if (binding) {
239
+ names.push({ name: binding.text, alias: alias?.text });
240
+ } else {
241
+ names.push({ name: item.text });
242
+ }
243
+ } else if (item.type === "scoped_identifier") {
244
+ const idents = collectIdentifiers(item);
245
+ names.push({ name: idents[idents.length - 1] ?? item.text });
246
+ } else if (item.text.includes(" as ")) {
247
+ const [head, alias] = item.text.split(/\s+as\s+/);
248
+ names.push({ name: (head ?? "").trim(), alias: alias?.trim() });
249
+ } else {
250
+ names.push({ name: item.text });
251
+ }
252
+ }
253
+ } else if (argument?.type === "use_wildcard") {
254
+ isGlob = true;
255
+ } else if (argument) {
256
+ const idents = collectIdentifiers(argument);
257
+ const last = idents[idents.length - 1] ?? argument.text;
258
+ names.push({ name: last });
259
+ const asMatch = text.match(/\s+as\s+(\w+)\s*;?\s*$/);
260
+ if (asMatch) names[0].alias = asMatch[1];
261
+ }
262
+ return {
263
+ path: path.trim(),
264
+ names,
265
+ isGlob,
266
+ line: node.startPosition.row + 1,
267
+ column: node.startPosition.column
268
+ };
269
+ }
270
+ function extractFunction(node, attrs, inheritedTestConfig, isMethod) {
271
+ const nameNode = node.childForFieldName("name");
272
+ const name = nameNode?.text ?? "<anon>";
273
+ const params = node.childForFieldName("parameters");
274
+ const body = node.childForFieldName("body");
275
+ const visibilityMod = node.namedChild(0);
276
+ const isPublic = visibilityMod?.type === "visibility_modifier";
277
+ let receiver;
278
+ if (isMethod && params) {
279
+ const selfParam = findSelfParameter(params);
280
+ if (selfParam) receiver = selfParam.text;
281
+ }
282
+ const bodyLines = body ? body.endPosition.row - body.startPosition.row + 1 : 0;
283
+ const inTestConfig = inheritedTestConfig || attrs.isTest || attrs.isTestCfg || isFunctionAttrTest(node);
284
+ return {
285
+ name,
286
+ line: node.startPosition.row + 1,
287
+ column: node.startPosition.column,
288
+ isPublic,
289
+ isMethod,
290
+ receiver,
291
+ bodyLines,
292
+ inTestConfig
293
+ };
294
+ }
295
+ function extractStruct(node, attrs) {
296
+ const nameNode = node.childForFieldName("name");
297
+ return {
298
+ name: nameNode?.text ?? "<anon>",
299
+ line: node.startPosition.row + 1,
300
+ column: node.startPosition.column,
301
+ isPublic: hasVisibility(node),
302
+ isDerive: attrs.derives.length > 0,
303
+ derives: [...attrs.derives]
304
+ };
305
+ }
306
+ function extractTrait(node, _attrs) {
307
+ const nameNode = node.childForFieldName("name");
308
+ return {
309
+ name: nameNode?.text ?? "<anon>",
310
+ line: node.startPosition.row + 1,
311
+ column: node.startPosition.column,
312
+ isPublic: hasVisibility(node)
313
+ };
314
+ }
315
+ function extractImpl(node, _attrs, _ctx) {
316
+ const traitNode = node.childForFieldName("trait");
317
+ const typeNode = node.childForFieldName("type");
318
+ const typeText = typeNode?.text ?? "<anon>";
319
+ const traitText = traitNode?.text;
320
+ const body = node.childForFieldName("body");
321
+ const methods = [];
322
+ if (body) {
323
+ for (let i = 0; i < body.namedChildCount; i++) {
324
+ const child = body.namedChild(i);
325
+ if (child?.type === "function_item") {
326
+ const m = child.childForFieldName("name");
327
+ if (m) methods.push(m.text);
328
+ }
329
+ }
330
+ }
331
+ return {
332
+ entry: {
333
+ type: typeText,
334
+ trait: traitText ?? void 0,
335
+ methods,
336
+ line: node.startPosition.row + 1,
337
+ column: node.startPosition.column
338
+ }
339
+ };
340
+ }
341
+ function findUseListNode(argument) {
342
+ if (!argument) return null;
343
+ if (argument.type === "use_list") return argument;
344
+ if (argument.type === "scoped_use_list") {
345
+ for (let i = 0; i < argument.namedChildCount; i++) {
346
+ const c = argument.namedChild(i);
347
+ if (c?.type === "use_list") return c;
348
+ }
349
+ }
350
+ return null;
351
+ }
352
+ function getField(node, fieldName) {
353
+ return node.childForFieldName(fieldName);
354
+ }
355
+ function collectIdentifiers(node) {
356
+ const out = [];
357
+ for (let i = 0; i < node.namedChildCount; i++) {
358
+ const child = node.namedChild(i);
359
+ if (!child) continue;
360
+ if (child.type === "identifier" || child.type === "type_identifier") {
361
+ out.push(child.text);
362
+ } else if (child.type === "scoped_identifier" || child.type === "nested_identifier") {
363
+ out.push(...collectIdentifiers(child));
364
+ }
365
+ }
366
+ return out;
367
+ }
368
+ function hasVisibility(node) {
369
+ return node.namedChild(0)?.type === "visibility_modifier";
370
+ }
371
+ function isInImplBlock(node) {
372
+ for (let p = node.parent; p; p = p.parent) {
373
+ if (p.type === "impl_item") return true;
374
+ if (p.type === "function_item" || p.type === "source_file") return false;
375
+ }
376
+ return false;
377
+ }
378
+ function findSelfParameter(params) {
379
+ for (let i = 0; i < params.namedChildCount; i++) {
380
+ const child = params.namedChild(i);
381
+ if (child?.type === "self_parameter") return child;
382
+ }
383
+ return null;
384
+ }
385
+ function isFunctionAttrTest(node) {
386
+ void node;
387
+ return false;
388
+ }
389
+ var SERVICE_SUFFIXES, SERVICE_SUFFIX_GROUP, RUST_SERVICE_STRUCT_RE, RUST_SERVICE_IMPL_RE;
390
+ var init_rust = __esm({
391
+ "src/engine/visitors/rust.ts"() {
392
+ "use strict";
393
+ init_parser_rust();
394
+ SERVICE_SUFFIXES = [
395
+ "Service",
396
+ "Manager",
397
+ "Handler",
398
+ "Repository",
399
+ "Controller",
400
+ "Helper",
401
+ "Factory",
402
+ "Provider",
403
+ "Store",
404
+ "API",
405
+ "Client",
406
+ "Adapter",
407
+ "Resolver",
408
+ "Mapper",
409
+ "Transformer",
410
+ "Serializer",
411
+ "Validator",
412
+ "Strategy",
413
+ "Facade",
414
+ "Decorator",
415
+ "Observer",
416
+ "Builder",
417
+ "Command",
418
+ "Processor",
419
+ "Worker",
420
+ "Job",
421
+ "Actor",
422
+ "Executor"
423
+ ];
424
+ SERVICE_SUFFIX_GROUP = `(?:${SERVICE_SUFFIXES.join("|")})`;
425
+ RUST_SERVICE_STRUCT_RE = new RegExp(
426
+ `^(?:pub(?:\\(crate\\)|\\(super\\))?\\s+)?struct\\s+(\\w+?)${SERVICE_SUFFIX_GROUP}?\\b`,
427
+ "gm"
428
+ );
429
+ RUST_SERVICE_IMPL_RE = new RegExp(
430
+ `^impl(?:<[^>]+>)?\\s+(?:${SERVICE_SUFFIX_GROUP}\\s+for\\s+)?(\\w+?)${SERVICE_SUFFIX_GROUP}?\\b`,
431
+ "gm"
432
+ );
433
+ }
434
+ });
435
+
21
436
  // src/engine/worker.ts
22
437
  var worker_exports = {};
23
438
  __export(worker_exports, {
@@ -4258,7 +4673,7 @@ function parseBlankModule(source) {
4258
4673
  tsx: false,
4259
4674
  target: "es2022"
4260
4675
  });
4261
- return { ast, source: replaced };
4676
+ return { ast, source };
4262
4677
  }
4263
4678
  function parseScriptContent(content, isTypeScript) {
4264
4679
  if (isTypeScript) {
@@ -4344,8 +4759,16 @@ function parseSource(source, filePath) {
4344
4759
  // but no SWC support. Return a blank-padded empty module so
4345
4760
  // regex-only rules can still fire (markdown-leakage, comment-
4346
4761
  // ratio, etc.) without burning the parseError path.
4762
+ // v0.18.9: `.rs` is in the same bucket. The visitor layer
4763
+ // (`engine/visitors/rust.ts`) carries the tree-sitter-backed
4764
+ // parse + extractFacts attaches the result to `facts.v2.rustFile`.
4765
+ // The rule layer (`rules/rust/*.ts`) reads that field. parseBlankModule
4766
+ // lets the worker continue past the parser — without this, parseWithSwc
4767
+ // would throw on every .rs file, the worker would count it as a
4768
+ // parseError, and the v2-build's buildRustFileRecord would never run.
4347
4769
  case "py":
4348
4770
  case "go":
4771
+ case "rs":
4349
4772
  return parseBlankModule(source);
4350
4773
  default:
4351
4774
  return parseWithSwc(source, filePath);
@@ -6910,6 +7333,7 @@ function dispatchNode(node, parent, path, vctx) {
6910
7333
  }
6911
7334
 
6912
7335
  // src/engine/visitors/v2-build.ts
7336
+ init_rust();
6913
7337
  var TAILWIND_COLOR_RE = /^(?:bg|text|border|ring|from|to|via|fill|stroke)-([a-z]+-\d+|white|black|transparent|current|\[.+?\])$/;
6914
7338
  var TAILWIND_SPACING_RE = /^(?:[pm][xytrbl]?|gap|space-[xy])-(\d+(?:\.\d+)?)$/;
6915
7339
  var TAILWIND_RADIUS_RE = /^(?:rounded(?:-[a-z]+)?)-(.+)$/;
@@ -7090,9 +7514,60 @@ function buildV2Facts(facts, source, ext, framework, config, templateClassNames
7090
7514
  })),
7091
7515
  disabledRules: extractDisabledRules(source),
7092
7516
  templateClassNames,
7517
+ // v0.18.9 — populate the Rust AST record when the file is `.rs`.
7518
+ // Calling `parseRustFile` here keeps the dead-code detector's
7519
+ // import-binding pass a pure function over the same source the
7520
+ // walker saw. The native-binding guard lives inside
7521
+ // `parseRustFile` (returns an empty record when tree-sitter is
7522
+ // unavailable).
7523
+ rustFile: buildRustFileRecord(facts.filePath, source),
7093
7524
  _source: source
7094
7525
  };
7095
7526
  }
7527
+ function buildRustFileRecord(filePath, source) {
7528
+ if (!filePath.toLowerCase().endsWith(".rs")) return void 0;
7529
+ const structure = parseRustFile(filePath, source);
7530
+ return {
7531
+ imports: structure.imports.map((i) => ({
7532
+ path: i.path,
7533
+ names: i.names.map((n) => ({ name: n.name, ...n.alias ? { alias: n.alias } : {} })),
7534
+ isGlob: i.isGlob,
7535
+ line: i.line,
7536
+ column: i.column
7537
+ })),
7538
+ functions: structure.functions.map((f) => ({
7539
+ name: f.name,
7540
+ line: f.line,
7541
+ column: f.column,
7542
+ isPublic: f.isPublic,
7543
+ isMethod: f.isMethod,
7544
+ ...f.receiver ? { receiver: f.receiver } : {},
7545
+ bodyLines: f.bodyLines,
7546
+ inTestConfig: f.inTestConfig
7547
+ })),
7548
+ structs: structure.structs.map((s) => ({
7549
+ name: s.name,
7550
+ line: s.line,
7551
+ column: s.column,
7552
+ isPublic: s.isPublic,
7553
+ isDerive: s.isDerive,
7554
+ derives: [...s.derives]
7555
+ })),
7556
+ traits: structure.traits.map((t) => ({
7557
+ name: t.name,
7558
+ line: t.line,
7559
+ column: t.column,
7560
+ isPublic: t.isPublic
7561
+ })),
7562
+ impls: structure.impls.map((ip) => ({
7563
+ ...ip.trait ? { trait: ip.trait } : {},
7564
+ type: ip.type,
7565
+ methods: [...ip.methods],
7566
+ line: ip.line,
7567
+ column: ip.column
7568
+ }))
7569
+ };
7570
+ }
7096
7571
  function splitFilePath(filePath) {
7097
7572
  const baseName = filePath.split("/").pop() ?? filePath;
7098
7573
  const dotIdx = baseName.lastIndexOf(".");
@@ -34594,9 +35069,43 @@ var unusedImportRule = createRule({
34594
35069
  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.`
34595
35070
  });
34596
35071
  }
35072
+ if (facts.v2.rustFile) {
35073
+ const strippedSource = stripUseDeclarations(facts.v2._source ?? "");
35074
+ const referenced = collectRustReferencedNames(strippedSource);
35075
+ for (const imp of facts.v2.rustFile.imports) {
35076
+ for (const nameEntry of imp.names) {
35077
+ if (referenced.has(nameEntry.name)) continue;
35078
+ const source = ` from '${imp.path}'`;
35079
+ issues.push({
35080
+ ruleId: "dead/unused-import",
35081
+ category: "logic",
35082
+ severity: "low",
35083
+ aiSpecific: true,
35084
+ message: `Unused import: '${nameEntry.name}'${source}`,
35085
+ line: imp.line,
35086
+ column: imp.column,
35087
+ 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)].`
35088
+ });
35089
+ }
35090
+ }
35091
+ }
34597
35092
  return issues;
34598
35093
  }
34599
35094
  });
35095
+ function collectRustReferencedNames(source) {
35096
+ const out = /* @__PURE__ */ new Set();
35097
+ for (const m of source.matchAll(/\b([A-Za-z_][A-Za-z0-9_]*)\b/g)) {
35098
+ out.add(m[1]);
35099
+ }
35100
+ return out;
35101
+ }
35102
+ function stripUseDeclarations(source) {
35103
+ let out = source;
35104
+ out = out.replace(/^\s*use\s+[\s\S]*?;\s*$/gm, "");
35105
+ out = out.replace(/\/\/[^\n]*/g, "");
35106
+ out = out.replace(/\/\*[\s\S]*?\*\//g, "");
35107
+ return out;
35108
+ }
34600
35109
 
34601
35110
  // src/rules/dead/unused-local.ts
34602
35111
  var SKIP_NAMES = /* @__PURE__ */ new Set(["React", "_"]);
@@ -34757,6 +35266,9 @@ var expiredCodeExampleRule = createRule({
34757
35266
  const issues = [];
34758
35267
  const source = facts.v2?._source;
34759
35268
  if (!source) return issues;
35269
+ const packages = declaredPackages(context.cwd);
35270
+ const packageName = context.packageName;
35271
+ if (packageName) packages.add(packageName);
34760
35272
  const blocks = extractFencedCodeBlocks(source);
34761
35273
  for (const block of blocks) {
34762
35274
  if (!CODE_LANGS.has(block.lang)) continue;
@@ -34764,7 +35276,7 @@ var expiredCodeExampleRule = createRule({
34764
35276
  const imports = extractImports(block.body);
34765
35277
  for (const imp of imports) {
34766
35278
  const pkgName = stripSubpath(imp);
34767
- if (context.packages.has(pkgName)) continue;
35279
+ if (packages.has(pkgName)) continue;
34768
35280
  issues.push({
34769
35281
  ruleId: "docs/expired-code-example",
34770
35282
  category: "docs",
@@ -34785,6 +35297,7 @@ var expiredCodeExampleRule = createRule({
34785
35297
  var import_node_fs4 = require("fs");
34786
35298
  var import_node_path4 = require("path");
34787
35299
  var RESERVED = /* @__PURE__ */ new Set([
35300
+ // JS reserved words
34788
35301
  "true",
34789
35302
  "false",
34790
35303
  "null",
@@ -34884,7 +35397,472 @@ var RESERVED = /* @__PURE__ */ new Set([
34884
35397
  "next",
34885
35398
  "vue",
34886
35399
  "angular",
34887
- "svelte"
35400
+ "svelte",
35401
+ // Framework / runtime names
35402
+ "html",
35403
+ "astro",
35404
+ "python",
35405
+ "jvm",
35406
+ "kotlin",
35407
+ "swift",
35408
+ "dart",
35409
+ "ruby",
35410
+ "rust",
35411
+ "cpp",
35412
+ "go",
35413
+ "java",
35414
+ "php",
35415
+ "php-html",
35416
+ "csharp",
35417
+ "typescript",
35418
+ "javascript",
35419
+ "jsx",
35420
+ "tsx",
35421
+ "mjs",
35422
+ "cjs",
35423
+ "esnext",
35424
+ "es6",
35425
+ "es2022",
35426
+ "es2023",
35427
+ "esm",
35428
+ "cjs",
35429
+ "umd",
35430
+ "amd",
35431
+ "commonjs",
35432
+ "require",
35433
+ "module",
35434
+ "exports",
35435
+ "define",
35436
+ "global",
35437
+ "window",
35438
+ "document",
35439
+ "process",
35440
+ "console",
35441
+ "buffer",
35442
+ "stream",
35443
+ "fetch",
35444
+ "axios",
35445
+ "express",
35446
+ "fastify",
35447
+ "koa",
35448
+ "hapi",
35449
+ "nextjs",
35450
+ "nuxt",
35451
+ "remix",
35452
+ "gatsby",
35453
+ "sveltekit",
35454
+ "solid",
35455
+ "preact",
35456
+ "qwik",
35457
+ "lit",
35458
+ "stencil",
35459
+ "marko",
35460
+ "alpine",
35461
+ "stimulus",
35462
+ "turbo",
35463
+ "hotwire",
35464
+ // Models / providers
35465
+ "gpt",
35466
+ "claude",
35467
+ "gpt-3",
35468
+ "gpt-3.5",
35469
+ "gpt-4",
35470
+ "gpt-oss",
35471
+ "haiku",
35472
+ "sonnet",
35473
+ "opus",
35474
+ "aider",
35475
+ "tabby",
35476
+ "copilot",
35477
+ "cursor",
35478
+ "windsurf",
35479
+ "devin",
35480
+ "claude-code",
35481
+ // LLM-detection lingo
35482
+ "heuristic",
35483
+ "heuristics",
35484
+ "calibrate",
35485
+ "calibration",
35486
+ "calibrator",
35487
+ "corpus",
35488
+ "baseline",
35489
+ "baselines",
35490
+ "corpus-baselines",
35491
+ "lift",
35492
+ "recall",
35493
+ "precision",
35494
+ "fpRate",
35495
+ "ratio",
35496
+ "verdict",
35497
+ "USEFUL",
35498
+ "NOISY",
35499
+ "INVERTED",
35500
+ "HYGIENE",
35501
+ "DORMANT",
35502
+ "OK",
35503
+ "aiSpecific",
35504
+ "defaultOff",
35505
+ // Common slop-audit verbs/nouns
35506
+ "commit",
35507
+ "push",
35508
+ "reset",
35509
+ "rebase",
35510
+ "merge",
35511
+ "cherry-pick",
35512
+ "revert",
35513
+ "scan",
35514
+ "parse",
35515
+ "build",
35516
+ "test",
35517
+ "lint",
35518
+ "format",
35519
+ "check",
35520
+ "audit",
35521
+ "fix",
35522
+ "patch",
35523
+ "diff",
35524
+ "pr",
35525
+ "ci",
35526
+ "cd",
35527
+ "gh",
35528
+ "npm",
35529
+ "npx",
35530
+ "pnpm",
35531
+ "yaml",
35532
+ "json",
35533
+ "toml",
35534
+ "csv",
35535
+ "md",
35536
+ "mdx",
35537
+ "sh",
35538
+ "bash",
35539
+ "zsh",
35540
+ "fish",
35541
+ "ascii",
35542
+ "utf8",
35543
+ "utf-8",
35544
+ "base64",
35545
+ "hex",
35546
+ "binary",
35547
+ "text",
35548
+ // Common design / ui terms
35549
+ "flex",
35550
+ "grid",
35551
+ "auto",
35552
+ "min",
35553
+ "max",
35554
+ "fill",
35555
+ "stretch",
35556
+ "wrap",
35557
+ "nowrap",
35558
+ "inline",
35559
+ "block",
35560
+ "hidden",
35561
+ "visible",
35562
+ "static",
35563
+ "fixed",
35564
+ "absolute",
35565
+ "relative",
35566
+ "sticky",
35567
+ "pointer",
35568
+ "cursor",
35569
+ "focus",
35570
+ "hover",
35571
+ "active",
35572
+ "disabled",
35573
+ "readonly",
35574
+ "primary",
35575
+ "secondary",
35576
+ "tertiary",
35577
+ "success",
35578
+ "warning",
35579
+ "danger",
35580
+ "info",
35581
+ "muted",
35582
+ "sm",
35583
+ "md",
35584
+ "lg",
35585
+ "xl",
35586
+ "xxl",
35587
+ "xs",
35588
+ "2xl",
35589
+ "3xl",
35590
+ "4xl",
35591
+ // Math / types
35592
+ "array",
35593
+ "map",
35594
+ "set",
35595
+ "weakmap",
35596
+ "weakset",
35597
+ "object",
35598
+ "string",
35599
+ "number",
35600
+ "boolean",
35601
+ "bigint",
35602
+ "symbol",
35603
+ "null",
35604
+ "undefined",
35605
+ "any",
35606
+ "unknown",
35607
+ "never",
35608
+ "void",
35609
+ "readonly",
35610
+ "private",
35611
+ "public",
35612
+ "protected",
35613
+ "static",
35614
+ "abstract",
35615
+ "async",
35616
+ "generator",
35617
+ "iterator",
35618
+ "iterable",
35619
+ "promise",
35620
+ "observable",
35621
+ // Auth / domain
35622
+ "admin",
35623
+ "user",
35624
+ "guest",
35625
+ "anonymous",
35626
+ "authenticated",
35627
+ "unauthenticated",
35628
+ "jwt",
35629
+ "oauth",
35630
+ "oidc",
35631
+ "saml",
35632
+ "csrf",
35633
+ "xss",
35634
+ "sql",
35635
+ "nosql",
35636
+ "orm",
35637
+ "prisma",
35638
+ "drizzle",
35639
+ "sequelize",
35640
+ "mongoose",
35641
+ "redis",
35642
+ "postgres",
35643
+ "mysql",
35644
+ "sqlite",
35645
+ "kafka",
35646
+ "rabbitmq",
35647
+ "graphql",
35648
+ "rest",
35649
+ "grpc",
35650
+ "websocket",
35651
+ // slop-audit specific
35652
+ "slopbrick",
35653
+ "usebrick",
35654
+ "deadcode",
35655
+ "unused",
35656
+ "orphan",
35657
+ "zombie",
35658
+ "blocker",
35659
+ "warning",
35660
+ "info",
35661
+ "error",
35662
+ "verbose",
35663
+ "debug",
35664
+ "silly",
35665
+ "p50",
35666
+ "p90",
35667
+ "p95",
35668
+ "p99",
35669
+ "min",
35670
+ "max",
35671
+ "avg",
35672
+ "mean",
35673
+ "median",
35674
+ "ratchet",
35675
+ "tier",
35676
+ "composite",
35677
+ "fitness",
35678
+ "fpr",
35679
+ "tpr",
35680
+ "roc",
35681
+ "should",
35682
+ "could",
35683
+ "would",
35684
+ "might",
35685
+ "must",
35686
+ "shall",
35687
+ "may",
35688
+ "can",
35689
+ "todo",
35690
+ "fixme",
35691
+ "xxx",
35692
+ "hack",
35693
+ "note",
35694
+ "warning",
35695
+ "attention",
35696
+ "h1",
35697
+ "h2",
35698
+ "h3",
35699
+ "h4",
35700
+ "h5",
35701
+ "h6",
35702
+ "strong",
35703
+ "em",
35704
+ "b",
35705
+ "i",
35706
+ "u",
35707
+ "true",
35708
+ "false",
35709
+ "yes",
35710
+ "no",
35711
+ "on",
35712
+ "off",
35713
+ "enable",
35714
+ "disable",
35715
+ "ltr",
35716
+ "rtl",
35717
+ "auto",
35718
+ "start",
35719
+ "end",
35720
+ "center",
35721
+ "baseline",
35722
+ "stretch",
35723
+ "rounded",
35724
+ "sharp",
35725
+ "outline",
35726
+ "ghost",
35727
+ "link",
35728
+ "filled",
35729
+ "row",
35730
+ "col",
35731
+ "gap",
35732
+ "pad",
35733
+ "margin",
35734
+ "padding",
35735
+ "border",
35736
+ "shadow",
35737
+ "transparent",
35738
+ "currentcolor",
35739
+ "inherit",
35740
+ "initial",
35741
+ "unset",
35742
+ "revert",
35743
+ "hover",
35744
+ "focus",
35745
+ "active",
35746
+ "disabled",
35747
+ "checked",
35748
+ "indeterminate",
35749
+ "open",
35750
+ "close",
35751
+ "expanded",
35752
+ "collapsed",
35753
+ "selected",
35754
+ "pressed",
35755
+ // Web/CSS
35756
+ "div",
35757
+ "span",
35758
+ "p",
35759
+ "a",
35760
+ "img",
35761
+ "ul",
35762
+ "ol",
35763
+ "li",
35764
+ "table",
35765
+ "tr",
35766
+ "td",
35767
+ "th",
35768
+ "thead",
35769
+ "tbody",
35770
+ "tfoot",
35771
+ "caption",
35772
+ "figure",
35773
+ "figcaption",
35774
+ "main",
35775
+ "section",
35776
+ "article",
35777
+ "aside",
35778
+ "header",
35779
+ "footer",
35780
+ "nav",
35781
+ "form",
35782
+ "input",
35783
+ "button",
35784
+ "select",
35785
+ "option",
35786
+ "textarea",
35787
+ "label",
35788
+ "fieldset",
35789
+ "legend",
35790
+ "details",
35791
+ "summary",
35792
+ "dialog",
35793
+ "menu",
35794
+ "menuitem",
35795
+ "template",
35796
+ "slot",
35797
+ "picture",
35798
+ "source",
35799
+ "track",
35800
+ "video",
35801
+ "audio",
35802
+ "canvas",
35803
+ "svg",
35804
+ "iframe",
35805
+ "embed",
35806
+ "object",
35807
+ "portal",
35808
+ // Common business terms
35809
+ "api",
35810
+ "cli",
35811
+ "ui",
35812
+ "ux",
35813
+ "sdk",
35814
+ "ide",
35815
+ "cli",
35816
+ "docs",
35817
+ "doc",
35818
+ "blog",
35819
+ "post",
35820
+ "page",
35821
+ "view",
35822
+ "tab",
35823
+ "panel",
35824
+ "card",
35825
+ "list",
35826
+ "grid",
35827
+ "form",
35828
+ "modal",
35829
+ "menu",
35830
+ "button",
35831
+ "icon",
35832
+ "avatar",
35833
+ "badge",
35834
+ "chip",
35835
+ "tooltip",
35836
+ "popover",
35837
+ "dropdown",
35838
+ "banner",
35839
+ "alert",
35840
+ "toast",
35841
+ "notification",
35842
+ "drawer",
35843
+ "sidebar",
35844
+ "navbar",
35845
+ "header",
35846
+ "footer",
35847
+ "hero",
35848
+ "cta",
35849
+ "cta-primary",
35850
+ "cta-secondary",
35851
+ "pricing",
35852
+ "price",
35853
+ "cost",
35854
+ "rate",
35855
+ "percent",
35856
+ "pct",
35857
+ "count",
35858
+ "total",
35859
+ "small",
35860
+ "medium",
35861
+ "large",
35862
+ "xl",
35863
+ "xxl",
35864
+ "tiny",
35865
+ "huge"
34888
35866
  ]);
34889
35867
  var SOURCE_EXTS = /* @__PURE__ */ new Set([".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"]);
34890
35868
  var SOURCE_ROOTS = ["src", "lib", "app", "components"];
@@ -34922,7 +35900,12 @@ function collectExports(cwd) {
34922
35900
  /\bexport\s+class\s+([A-Za-z_$][\w$]*)/g,
34923
35901
  /\bexport\s+interface\s+([A-Za-z_$][\w$]*)/g,
34924
35902
  /\bexport\s+type\s+([A-Za-z_$][\w$]*)/g,
34925
- /\bexport\s+default\s+(?:function\s+|class\s+)?([A-Za-z_$][\w$]*)/g
35903
+ /\bexport\s+default\s+(?:function\s+|class\s+)?([A-Za-z_$][\w$]*)/g,
35904
+ // v0.18.6: also collect field names from `export interface` and
35905
+ // `export type` declarations. Without this, fields like
35906
+ // `crossFileDrift`, `aiQuality`, `engineeringHygiene` are
35907
+ // flagged as stale even though they're valid type fields.
35908
+ /^\s*(?:readonly\s+)?([A-Za-z_$][\w$]*)\s*[?:]/gm
34926
35909
  ]) {
34927
35910
  let m;
34928
35911
  while ((m = re.exec(source)) !== null) {
@@ -34933,6 +35916,21 @@ function collectExports(cwd) {
34933
35916
  }
34934
35917
  return out;
34935
35918
  }
35919
+ function looksLikeProseLabel(inside) {
35920
+ const trimmed = inside.trim();
35921
+ if (trimmed.length === 0) return false;
35922
+ if (trimmed.startsWith("`") || trimmed.startsWith("/")) return true;
35923
+ if (trimmed.includes("`")) return true;
35924
+ if (/\d+\s+[a-z]/i.test(trimmed)) return true;
35925
+ const parts = trimmed.split(",").map((s) => s.trim());
35926
+ if (parts.length >= 3) {
35927
+ const allNumeric = parts.every((p) => /^\d+\.?\d*$/.test(p));
35928
+ if (!allNumeric) return true;
35929
+ }
35930
+ if (trimmed.length > 40 && !trimmed.includes(",")) return true;
35931
+ if (trimmed.includes("\u2014") || trimmed.includes("\u2013")) return true;
35932
+ return false;
35933
+ }
34936
35934
  var staleFunctionReferenceRule = createRule({
34937
35935
  id: "docs/stale-function-reference",
34938
35936
  category: "docs",
@@ -34952,8 +35950,39 @@ var staleFunctionReferenceRule = createRule({
34952
35950
  if (text.length < 3) continue;
34953
35951
  if (RESERVED.has(text.toLowerCase())) continue;
34954
35952
  if (context.exports.has(text)) continue;
34955
- const end = Math.min(source.length, span.index + text.length + 50);
34956
- if (!/\(/.test(source.slice(span.index, end))) continue;
35953
+ const lineEnd = source.indexOf("\n", span.index);
35954
+ const restOfLine = source.slice(
35955
+ span.index,
35956
+ lineEnd === -1 ? source.length : lineEnd
35957
+ );
35958
+ const closeTick = restOfLine.indexOf("`", 1);
35959
+ if (closeTick === -1) continue;
35960
+ const afterTick = restOfLine.slice(closeTick + 1);
35961
+ const directCall = /^\s*\(/.test(afterTick);
35962
+ let identifierRepeats = false;
35963
+ if (!directCall) {
35964
+ const afterSpan = restOfLine.slice(closeTick + 1);
35965
+ const needle = text + "(";
35966
+ identifierRepeats = afterSpan.indexOf(needle) !== -1;
35967
+ }
35968
+ if (!directCall && !identifierRepeats) continue;
35969
+ const beforeTickIdx = span.index - 1;
35970
+ const beforeChar = beforeTickIdx >= 0 ? source[beforeTickIdx] : "";
35971
+ if (beforeChar === "." || beforeChar === "|") continue;
35972
+ const parenStart = restOfLine.indexOf("(", closeTick);
35973
+ const parenEnd = restOfLine.indexOf(")", parenStart);
35974
+ if (parenStart !== -1 && parenEnd !== -1) {
35975
+ const inside = restOfLine.slice(parenStart + 1, parenEnd);
35976
+ const trimmed = inside.trim();
35977
+ if (looksLikeProseLabel(inside)) continue;
35978
+ const looksLikeTypeAnnotation = !inside.includes(":") && (/\b(string|number|boolean|null|undefined|object|array|required|optional|categorical|direct|n\/a|\bmapped\b|0[\-–][0-9]+|v[0-9]|higher is better|lower is better|added in|deprecated|pr-[0-9])\b/i.test(
35979
+ inside
35980
+ ) || // Short single-word label (≤ 24 chars, no `,`,
35981
+ // doesn't look like a function arg). Real function
35982
+ // calls are usually longer or contain commas.
35983
+ trimmed.length > 0 && trimmed.length <= 24 && !trimmed.includes(",") && /[a-zA-Z]/.test(trimmed));
35984
+ if (looksLikeTypeAnnotation) continue;
35985
+ }
34957
35986
  issues.push({
34958
35987
  ruleId: "docs/stale-function-reference",
34959
35988
  category: "docs",
@@ -35025,7 +36054,33 @@ var ENGLISH_WORD_DENYLIST = /* @__PURE__ */ new Set([
35025
36054
  "jsx",
35026
36055
  "ok",
35027
36056
  "no",
35028
- "yes"
36057
+ "yes",
36058
+ // v0.18.6: common English adjectives / adverbs that frequently
36059
+ // appear in backticked prose but are not package names.
36060
+ "aspirational",
36061
+ "concrete",
36062
+ "abstract",
36063
+ "inline",
36064
+ "exposed",
36065
+ "deprecated",
36066
+ "experimental",
36067
+ "stable",
36068
+ "beta",
36069
+ "alpha",
36070
+ "wip",
36071
+ "draft",
36072
+ "final",
36073
+ "shim",
36074
+ "polyfill",
36075
+ "stub",
36076
+ "mock",
36077
+ "fake",
36078
+ "real",
36079
+ "false",
36080
+ "true",
36081
+ "optional",
36082
+ "required",
36083
+ "default"
35029
36084
  ]);
35030
36085
  var stalePackageReferenceRule = createRule({
35031
36086
  id: "docs/stale-package-reference",
@@ -35187,7 +36242,9 @@ var brokenLinkRule = createRule({
35187
36242
  if (target.startsWith("#")) continue;
35188
36243
  if (target.startsWith("//")) continue;
35189
36244
  if (target.startsWith("/")) continue;
35190
- const resolved = (0, import_node_path6.join)(docDir, target);
36245
+ const filePart = target.split("#")[0] ?? target;
36246
+ if (filePart === "") continue;
36247
+ const resolved = (0, import_node_path6.join)(docDir, filePart);
35191
36248
  if ((0, import_node_fs6.existsSync)(resolved)) continue;
35192
36249
  issues.push({
35193
36250
  ruleId: "docs/broken-link",
@@ -36961,6 +38018,326 @@ var uxPatternFragmentationRule = createRule({
36961
38018
  }
36962
38019
  });
36963
38020
 
38021
+ // src/rules/rust/stringly-typed.ts
38022
+ var SUSPECT_PARAM_NAMES = /* @__PURE__ */ new Set([
38023
+ "kind",
38024
+ "type",
38025
+ "mode",
38026
+ "event",
38027
+ "status",
38028
+ "category",
38029
+ "action",
38030
+ "state",
38031
+ "level",
38032
+ "role",
38033
+ "tier",
38034
+ "phase",
38035
+ "tag",
38036
+ "format",
38037
+ "shape",
38038
+ "direction",
38039
+ "side",
38040
+ "method"
38041
+ ]);
38042
+ var MAX_VARIANT_COUNT = 32;
38043
+ var rustStringlyTypedRule = createRule({
38044
+ id: "rust/stringly-typed",
38045
+ category: "logic",
38046
+ severity: "medium",
38047
+ aiSpecific: true,
38048
+ description: "String / &str parameter where a typed enum exists in the same file",
38049
+ create(_context) {
38050
+ return {};
38051
+ },
38052
+ analyze(_context, facts) {
38053
+ const issues = [];
38054
+ if (!facts.v2?.rustFile) return issues;
38055
+ const source = facts.v2._source ?? "";
38056
+ if (!source) return issues;
38057
+ const lineOffsets = buildLineOffsets2(source);
38058
+ const enumCandidates = collectEnumCandidates(source);
38059
+ if (enumCandidates.length === 0) return issues;
38060
+ for (const fn of facts.v2.rustFile.functions) {
38061
+ const paramText = extractParameterText(source, lineOffsets, fn);
38062
+ if (!paramText) continue;
38063
+ const matches = scanForStringlyParams(paramText);
38064
+ if (matches.length === 0) continue;
38065
+ issues.push({
38066
+ ruleId: "rust/stringly-typed",
38067
+ category: "logic",
38068
+ severity: "medium",
38069
+ aiSpecific: true,
38070
+ 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`,
38071
+ line: fn.line,
38072
+ column: fn.column,
38073
+ 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.`
38074
+ });
38075
+ }
38076
+ return issues;
38077
+ }
38078
+ });
38079
+ function collectEnumCandidates(source) {
38080
+ const out = [];
38081
+ const enumRe = /^(?:pub(?:\([^)]+\))?\s+)?enum\s+(\w+)\s*\{([^}]*)\}/gm;
38082
+ for (const m of source.matchAll(enumRe)) {
38083
+ const body = m[2] ?? "";
38084
+ const variants = body.split(/,(?![^()]*\))/).map((s) => s.trim()).filter((s) => /^[A-Za-z_][A-Za-z0-9_]*$/.test(s.split(/\s+/)[0] ?? ""));
38085
+ if (variants.length > MAX_VARIANT_COUNT) continue;
38086
+ if (variants.length < 2) continue;
38087
+ out.push({ name: m[1], variantCount: variants.length, line: lineOfMatch(source, m.index ?? 0) });
38088
+ }
38089
+ return out;
38090
+ }
38091
+ function lineOfMatch(source, index) {
38092
+ let line = 1;
38093
+ for (let i = 0; i < index && i < source.length; i++) {
38094
+ if (source[i] === "\n") line++;
38095
+ }
38096
+ return line;
38097
+ }
38098
+ function buildLineOffsets2(source) {
38099
+ const out = [0];
38100
+ for (let i = 0; i < source.length; i++) {
38101
+ if (source[i] === "\n") out.push(i + 1);
38102
+ }
38103
+ return out;
38104
+ }
38105
+ function extractParameterText(source, lineOffsets, fn) {
38106
+ const start = lineOffsets[Math.max(0, fn.line - 1)] ?? 0;
38107
+ const head = source.slice(start, start + 400);
38108
+ const openIdx = head.indexOf("(");
38109
+ if (openIdx < 0) return "";
38110
+ let closeIdx = -1;
38111
+ let depth = 0;
38112
+ for (let i = openIdx; i < head.length; i++) {
38113
+ if (head[i] === "(") depth++;
38114
+ else if (head[i] === ")") {
38115
+ depth--;
38116
+ if (depth === 0) {
38117
+ closeIdx = i;
38118
+ break;
38119
+ }
38120
+ }
38121
+ }
38122
+ if (closeIdx < 0) return "";
38123
+ return head.slice(openIdx + 1, closeIdx);
38124
+ }
38125
+ function scanForStringlyParams(paramText) {
38126
+ const out = [];
38127
+ for (const m of paramText.matchAll(
38128
+ /\b([a-z_][a-zA-Z0-9_]*)\s*:\s*(&\s*(?:mut\s+)?(?:str|String)\b)/g
38129
+ )) {
38130
+ const name = m[1];
38131
+ const type = m[2];
38132
+ if (!SUSPECT_PARAM_NAMES.has(name)) continue;
38133
+ out.push({ name, type });
38134
+ }
38135
+ return out;
38136
+ }
38137
+
38138
+ // src/rules/rust/todo-macro.ts
38139
+ init_parser_rust();
38140
+ var TODO_MACROS = /* @__PURE__ */ new Set(["todo", "unimplemented", "todo_unimplemented"]);
38141
+ var rustTodoMacroRule = createRule({
38142
+ id: "rust/todo-macro",
38143
+ category: "logic",
38144
+ severity: "medium",
38145
+ aiSpecific: true,
38146
+ description: "todo!() / unimplemented!() macro invocation in production code",
38147
+ create(_context) {
38148
+ return {};
38149
+ },
38150
+ analyze(_context, facts) {
38151
+ const issues = [];
38152
+ if (!facts.v2?.rustFile) return issues;
38153
+ const source = facts.v2._source ?? "";
38154
+ if (!source) return issues;
38155
+ const tree = parseRust(source);
38156
+ if (!tree) return issues;
38157
+ const testScopes = /* @__PURE__ */ new Set();
38158
+ for (const fn of facts.v2.rustFile.functions) {
38159
+ if (fn.inTestConfig && fn.name) testScopes.add(fn.name);
38160
+ }
38161
+ collectMacroIssues(tree.rootNode, testScopes, issues);
38162
+ return issues;
38163
+ }
38164
+ });
38165
+ function collectMacroIssues(node, testScopes, issues) {
38166
+ if (node.type === "macro_invocation") {
38167
+ const text = node.text;
38168
+ const m = text.match(/^([A-Za-z_][A-Za-z0-9_]*)/);
38169
+ const macroName = m?.[1] ?? "";
38170
+ if (TODO_MACROS.has(macroName)) {
38171
+ if (!isInsideMacroDefinition(node) && !isInsideTestFunction(node, testScopes)) {
38172
+ issues.push({
38173
+ ruleId: "rust/todo-macro",
38174
+ category: "logic",
38175
+ severity: "medium",
38176
+ aiSpecific: true,
38177
+ message: `'${macroName}!()' in production code \u2014 both expand to panic!()`,
38178
+ line: node.startPosition.row + 1,
38179
+ column: node.startPosition.column,
38180
+ 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.`
38181
+ });
38182
+ }
38183
+ }
38184
+ }
38185
+ for (let i = 0; i < node.namedChildCount; i++) {
38186
+ const child = node.namedChild(i);
38187
+ if (child) collectMacroIssues(child, testScopes, issues);
38188
+ }
38189
+ }
38190
+ function isInsideMacroDefinition(node) {
38191
+ for (let p = node.parent; p; p = p.parent) {
38192
+ if (p.type === "macro_definition") return true;
38193
+ if (p.type === "source_file") return false;
38194
+ }
38195
+ return false;
38196
+ }
38197
+ function isInsideTestFunction(node, testScopes) {
38198
+ for (let p = node.parent; p; p = p.parent) {
38199
+ if (p.type === "function_item") {
38200
+ const nameField = p.childForFieldName("name");
38201
+ const name = nameField?.text;
38202
+ if (name && testScopes.has(name)) return true;
38203
+ if (p.text.startsWith("#[test]") || p.text.startsWith("#[cfg(test)]")) return true;
38204
+ return false;
38205
+ }
38206
+ if (p.type === "source_file") return false;
38207
+ }
38208
+ return false;
38209
+ }
38210
+
38211
+ // src/rules/rust/unused-pub-fn.ts
38212
+ var API_CONVENTION_NAMES = /* @__PURE__ */ new Set([
38213
+ "new",
38214
+ "default",
38215
+ "from",
38216
+ "from_str",
38217
+ "from_iter",
38218
+ "try_from",
38219
+ "into",
38220
+ "into_iter",
38221
+ "try_into",
38222
+ "as_ref",
38223
+ "as_mut",
38224
+ "clone",
38225
+ "fmt",
38226
+ "eq",
38227
+ "hash",
38228
+ "partial_cmp",
38229
+ "cmp",
38230
+ "ord",
38231
+ "partial_eq"
38232
+ ]);
38233
+ var rustUnusedPubFnRule = createRule({
38234
+ id: "rust/unused-pub-fn",
38235
+ category: "logic",
38236
+ severity: "low",
38237
+ aiSpecific: true,
38238
+ description: "Public function in a Rust file that has no in-file references",
38239
+ create(_context) {
38240
+ return {};
38241
+ },
38242
+ analyze(_context, facts) {
38243
+ const issues = [];
38244
+ if (!facts.v2?.rustFile) return issues;
38245
+ const rust = facts.v2.rustFile;
38246
+ const referenced = collectReferencedNames(facts.v2._source ?? "");
38247
+ for (const fn of rust.functions) {
38248
+ if (!fn.isPublic) continue;
38249
+ if (API_CONVENTION_NAMES.has(fn.name)) continue;
38250
+ if (fn.inTestConfig) continue;
38251
+ if (referenced.has(fn.name)) continue;
38252
+ issues.push({
38253
+ ruleId: "rust/unused-pub-fn",
38254
+ category: "logic",
38255
+ severity: "low",
38256
+ aiSpecific: true,
38257
+ message: `Public function '${fn.name}' is not referenced anywhere in the file`,
38258
+ line: fn.line,
38259
+ column: fn.column,
38260
+ 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.`
38261
+ });
38262
+ }
38263
+ return issues;
38264
+ }
38265
+ });
38266
+ function collectReferencedNames(source) {
38267
+ const out = /* @__PURE__ */ new Set();
38268
+ for (const m of source.matchAll(/\b([A-Za-z_][A-Za-z0-9_]*)\b/g)) {
38269
+ out.add(m[1]);
38270
+ }
38271
+ return out;
38272
+ }
38273
+
38274
+ // src/rules/rust/unwrap-in-production.ts
38275
+ init_parser_rust();
38276
+ var UNWRAP_METHODS = /* @__PURE__ */ new Set(["unwrap", "expect", "unwrap_or_else"]);
38277
+ var rustUnwrapInProductionRule = createRule({
38278
+ id: "rust/unwrap-in-production",
38279
+ category: "logic",
38280
+ severity: "medium",
38281
+ aiSpecific: true,
38282
+ description: ".unwrap() / .expect() called outside of #[cfg(test)] / #[test] scope",
38283
+ create(_context) {
38284
+ return {};
38285
+ },
38286
+ analyze(_context, facts) {
38287
+ const issues = [];
38288
+ if (!facts.v2?.rustFile) return issues;
38289
+ const source = facts.v2._source ?? "";
38290
+ if (!source) return issues;
38291
+ const tree = parseRust(source);
38292
+ if (!tree) return issues;
38293
+ const testScopes = /* @__PURE__ */ new Set();
38294
+ for (const fn of facts.v2.rustFile.functions) {
38295
+ if (fn.inTestConfig && fn.name) testScopes.add(fn.name);
38296
+ }
38297
+ collectUnwrapIssues(tree.rootNode, testScopes, issues);
38298
+ return issues;
38299
+ }
38300
+ });
38301
+ function collectUnwrapIssues(node, testScopes, issues) {
38302
+ if (node.type === "call_expression") {
38303
+ const fn = node.childForFieldName("function");
38304
+ if (fn && fn.type === "field_expression") {
38305
+ const field = fn.childForFieldName("field");
38306
+ if (field && field.type === "field_identifier" && UNWRAP_METHODS.has(field.text)) {
38307
+ if (!isInsideTestFunction2(node, testScopes)) {
38308
+ issues.push({
38309
+ ruleId: "rust/unwrap-in-production",
38310
+ category: "logic",
38311
+ severity: "medium",
38312
+ aiSpecific: true,
38313
+ message: `'.${field.text}()' called in production code \u2014 panic risk on Err/None`,
38314
+ line: node.startPosition.row + 1,
38315
+ column: node.startPosition.column,
38316
+ 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.`
38317
+ });
38318
+ }
38319
+ }
38320
+ }
38321
+ }
38322
+ for (let i = 0; i < node.namedChildCount; i++) {
38323
+ const child = node.namedChild(i);
38324
+ if (child) collectUnwrapIssues(child, testScopes, issues);
38325
+ }
38326
+ }
38327
+ function isInsideTestFunction2(node, testScopes) {
38328
+ for (let p = node.parent; p; p = p.parent) {
38329
+ if (p.type === "function_item") {
38330
+ const nameField = p.childForFieldName("name");
38331
+ const name = nameField?.text;
38332
+ if (name && testScopes.has(name)) return true;
38333
+ if (p.text.startsWith("#[test]") || p.text.startsWith("#[cfg(test)]")) return true;
38334
+ return false;
38335
+ }
38336
+ if (p.type === "source_file") return false;
38337
+ }
38338
+ return false;
38339
+ }
38340
+
36964
38341
  // src/rules/security/dangerous-cors.ts
36965
38342
  var HEADER_LITERAL_RE = /['"]Access-Control-Allow-Origin['"]\s*[,:=]\s*['"]\*['"]/g;
36966
38343
  var CORS_BLOCK_RE = /\bcors\s*\(\s*\{([^}]*)\}\s*\)/g;
@@ -39992,6 +41369,10 @@ var builtinRules = [
39992
41369
  halsteadAnomalyRule,
39993
41370
  terminologyDriftRule,
39994
41371
  uxPatternFragmentationRule,
41372
+ rustStringlyTypedRule,
41373
+ rustTodoMacroRule,
41374
+ rustUnusedPubFnRule,
41375
+ rustUnwrapInProductionRule,
39995
41376
  dangerousCorsRule,
39996
41377
  evalRule,
39997
41378
  exposedEnvVarRule,
@@ -40066,6 +41447,22 @@ var RuleRegistry = class {
40066
41447
  if (!filter) return list;
40067
41448
  return list.filter((r) => filter.kind === "ai" ? r.aiSpecific : !r.aiSpecific);
40068
41449
  }
41450
+ /** v0.18.8: remove every rule where `predicate(rule)` returns true.
41451
+ * Used by focused calibration scripts to scan a single category
41452
+ * without instantiating all 99 rules. */
41453
+ removeWhere(predicate) {
41454
+ let removed = 0;
41455
+ for (const [id, rule] of this.rules) {
41456
+ if (predicate(rule)) {
41457
+ this.rules.delete(id);
41458
+ removed++;
41459
+ }
41460
+ }
41461
+ return removed;
41462
+ }
41463
+ all() {
41464
+ return Array.from(this.rules.values());
41465
+ }
40069
41466
  createContexts(config, filePath, cwd, hotspotIssues = []) {
40070
41467
  const context = {
40071
41468
  config,
@@ -40086,1044 +41483,1793 @@ var RuleRegistry = class {
40086
41483
 
40087
41484
  // src/rules/signal-strength.json
40088
41485
  var signal_strength_default = {
40089
- "logic/math-console-log-storm": {
40090
- recall: 7e-3,
40091
- fpRate: 1e-3,
40092
- ratio: 6.71,
40093
- precision: 0.8968,
40094
- lastCalibratedAt: "2026-06-27T12:00:00Z",
41486
+ "ai/any-density": {
41487
+ recall: 6e-3,
41488
+ fpRate: 37e-4,
41489
+ ratio: 175.31,
41490
+ precision: 0.6523,
41491
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
40095
41492
  verdict: "USEFUL",
40096
- _calibrationNote: "v7 corpus re-calibration (2026-06-27, min-date=2025-01-01): 184488 neg + 239054 pos. USEFUL \u2014 TP=1678, FP=193, P=89.7%, FPR=0.10%, lift=6.7. aiSpecific=True.",
40097
- aiSpecific: true
41493
+ _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).",
41494
+ aiSpecific: true,
41495
+ _v7Verdict: "USEFUL",
41496
+ _v7Lift: 153.41,
41497
+ _v7Recall: 55e-4,
41498
+ _v7FpRate: 41e-4,
41499
+ _v7Precision: 0.634,
41500
+ _v8Verdict: "USEFUL",
41501
+ _v8Lift: 271.97
40098
41502
  },
40099
- "logic/math-any-density": {
40100
- recall: 16e-4,
40101
- fpRate: 13e-4,
40102
- ratio: 1.17,
40103
- precision: 0.6035,
40104
- lastCalibratedAt: "2026-06-27T12:00:00Z",
40105
- verdict: "NOISY",
40106
- _calibrationNote: "v7 corpus re-calibration (2026-06-27, min-date=2025-01-01): 184488 neg + 239054 pos. NOISY \u2014 TP=376, FP=247, P=60.4%, FPR=0.13%, lift=1.2. aiSpecific=True.",
40107
- defaultOff: true,
40108
- aiSpecific: true
41503
+ "ai/comment-ratio": {
41504
+ recall: 0.2771,
41505
+ fpRate: 0.1578,
41506
+ ratio: 4.26,
41507
+ precision: 0.6721,
41508
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
41509
+ verdict: "USEFUL",
41510
+ _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).",
41511
+ aiSpecific: true,
41512
+ _v7Verdict: "USEFUL",
41513
+ _v7Lift: 4.11,
41514
+ _v7Recall: 0.2545,
41515
+ _v7FpRate: 0.1629,
41516
+ _v7Precision: 0.6687,
41517
+ _v8Verdict: "USEFUL",
41518
+ _v8Lift: 4.73
40109
41519
  },
40110
- "logic/boundary-violation": {
40111
- recall: 0.0263,
40112
- fpRate: 0.0175,
40113
- ratio: 1.5,
40114
- precision: 0.6601,
40115
- lastCalibratedAt: "2026-06-27T12:00:00Z",
40116
- verdict: "HYGIENE",
40117
- _calibrationNote: "v7 corpus re-calibration (2026-06-27, min-date=2025-01-01): 184488 neg + 239054 pos. HYGIENE \u2014 TP=6282, FP=3235, P=66.0%, FPR=1.75%, lift=1.5. aiSpecific=False.",
40118
- aiSpecific: false
41520
+ "ai/compression-profile": {
41521
+ recall: 0.3478,
41522
+ fpRate: 0.1488,
41523
+ ratio: 4.92,
41524
+ precision: 0.7318,
41525
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
41526
+ verdict: "USEFUL",
41527
+ _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).",
41528
+ aiSpecific: true,
41529
+ _v7Verdict: "USEFUL",
41530
+ _v7Lift: 4.89,
41531
+ _v7Recall: 0.3166,
41532
+ _v7FpRate: 0.1498,
41533
+ _v7Precision: 0.732,
41534
+ _v8Verdict: "USEFUL",
41535
+ _v8Lift: 5
40119
41536
  },
40120
- "logic/reactive-hook-soup": {
40121
- recall: 38e-4,
41537
+ "ai/console-debug-storm": {
41538
+ recall: 73e-4,
40122
41539
  fpRate: 9e-4,
40123
- ratio: 4.29,
40124
- precision: 0.8476,
40125
- lastCalibratedAt: "2026-06-27T12:00:00Z",
41540
+ ratio: 949.21,
41541
+ precision: 0.9,
41542
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
40126
41543
  verdict: "USEFUL",
40127
- _calibrationNote: "v7 corpus re-calibration (2026-06-27, min-date=2025-01-01): 184488 neg + 239054 pos. USEFUL \u2014 TP=901, FP=162, P=84.8%, FPR=0.09%, lift=4.3. aiSpecific=True.",
40128
- aiSpecific: true
41544
+ _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).",
41545
+ aiSpecific: true,
41546
+ _v7Verdict: "USEFUL",
41547
+ _v7Lift: 960.19,
41548
+ _v7Recall: 81e-4,
41549
+ _v7FpRate: 1e-3,
41550
+ _v7Precision: 0.9161,
41551
+ _v8Verdict: "USEFUL",
41552
+ _v8Lift: 845.55
40129
41553
  },
40130
- "logic/optimistic-no-rollback": {
40131
- recall: 12e-4,
40132
- fpRate: 3e-4,
40133
- ratio: 3.61,
40134
- precision: 0.824,
40135
- lastCalibratedAt: "2026-06-27T12:00:00Z",
41554
+ "ai/default-react-stack": {
41555
+ recall: 1e-3,
41556
+ fpRate: 0,
41557
+ ratio: 251225.49,
41558
+ precision: 0.9966,
41559
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
40136
41560
  verdict: "USEFUL",
40137
- _calibrationNote: "v7 corpus re-calibration (2026-06-27, min-date=2025-01-01): 184488 neg + 239054 pos. USEFUL \u2014 TP=281, FP=60, P=82.4%, FPR=0.03%, lift=3.6. aiSpecific=True.",
40138
- aiSpecific: true
41561
+ _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).",
41562
+ aiSpecific: true,
41563
+ _v7Verdict: "USEFUL",
41564
+ _v7Lift: 182622.43,
41565
+ _v7Recall: 1e-3,
41566
+ _v7FpRate: 0,
41567
+ _v7Precision: 0.9957,
41568
+ _v8Verdict: "USEFUL",
41569
+ _v8Lift: 99999
40139
41570
  },
40140
- "logic/zombie-state": {
40141
- recall: 1e-4,
40142
- fpRate: 0,
40143
- ratio: 9.26,
40144
- precision: 0.9231,
40145
- lastCalibratedAt: "2026-06-27T12:00:00Z",
41571
+ "ai/errors-near-eof": {
41572
+ recall: 0.0948,
41573
+ fpRate: 0.052,
41574
+ ratio: 13.09,
41575
+ precision: 0.6803,
41576
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
40146
41577
  verdict: "USEFUL",
40147
- _calibrationNote: "v7 corpus re-calibration (2026-06-27, min-date=2025-01-01): 184488 neg + 239054 pos. USEFUL \u2014 TP=24, FP=2, P=92.3%, FPR=0.00%, lift=9.3. aiSpecific=True.",
40148
- aiSpecific: true
41578
+ _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).",
41579
+ aiSpecific: true,
41580
+ _v7Verdict: "USEFUL",
41581
+ _v7Lift: 11.29,
41582
+ _v7Recall: 0.0704,
41583
+ _v7FpRate: 0.0551,
41584
+ _v7Precision: 0.6225,
41585
+ _v8Verdict: "USEFUL",
41586
+ _v8Lift: 18.16
40149
41587
  },
40150
- "logic/math-gini-class-usage": {
40151
- recall: 13e-4,
41588
+ "ai/fetch-default-overuse": {
41589
+ recall: 27e-4,
40152
41590
  fpRate: 3e-4,
40153
- ratio: 5.09,
40154
- precision: 0.8683,
40155
- lastCalibratedAt: "2026-06-27T12:00:00Z",
41591
+ ratio: 2679.84,
41592
+ precision: 0.9036,
41593
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
40156
41594
  verdict: "USEFUL",
40157
- _calibrationNote: "v7 corpus re-calibration (2026-06-27, min-date=2025-01-01): 184488 neg + 239054 pos. USEFUL \u2014 TP=310, FP=47, P=86.8%, FPR=0.03%, lift=5.1. aiSpecific=True.",
40158
- aiSpecific: true
41595
+ _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).",
41596
+ aiSpecific: true,
41597
+ _v7Verdict: "USEFUL",
41598
+ _v7Lift: 2166.14,
41599
+ _v7Recall: 28e-4,
41600
+ _v7FpRate: 4e-4,
41601
+ _v7Precision: 0.8976,
41602
+ _v8Verdict: "USEFUL",
41603
+ _v8Lift: 7139.19
40159
41604
  },
40160
- "visual/math-color-cluster": {
40161
- recall: 2e-4,
41605
+ "ai/library-reinvention": {
41606
+ recall: 3e-4,
40162
41607
  fpRate: 0,
40163
- ratio: 8.95,
40164
- precision: 0.9206,
40165
- lastCalibratedAt: "2026-06-27T12:00:00Z",
40166
- verdict: "USEFUL",
40167
- _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.",
40168
- aiSpecific: true
40169
- },
40170
- "visual/math-default-font": {
40171
- recall: 13e-4,
40172
- fpRate: 4e-4,
40173
- ratio: 3.4,
40174
- precision: 0.8151,
40175
- lastCalibratedAt: "2026-06-27T12:00:00Z",
41608
+ ratio: 47415.05,
41609
+ precision: 0.9405,
41610
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
40176
41611
  verdict: "USEFUL",
40177
- _calibrationNote: "v7 corpus re-calibration (2026-06-27, min-date=2025-01-01): 184488 neg + 239054 pos. USEFUL \u2014 TP=313, FP=71, P=81.5%, FPR=0.04%, lift=3.4. aiSpecific=True.",
40178
- aiSpecific: true
41612
+ _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).",
41613
+ aiSpecific: true,
41614
+ _v7Verdict: "USEFUL",
41615
+ _v7Lift: 34024.44,
41616
+ _v7Recall: 3e-4,
41617
+ _v7FpRate: 0,
41618
+ _v7Precision: 0.9275,
41619
+ _v8Verdict: "USEFUL",
41620
+ _v8Lift: 99999
40179
41621
  },
40180
- "visual/math-gradient-hue-rotation": {
41622
+ "ai/log-rank-histogram": {
40181
41623
  recall: 0,
40182
41624
  fpRate: 0,
40183
41625
  ratio: 0,
40184
41626
  precision: 0,
40185
- lastCalibratedAt: "2026-06-25T00:00:00Z",
41627
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
40186
41628
  verdict: "DORMANT",
40187
- defaultOff: true,
40188
- _calibrationNote: "v0.10.1 ship \u2014 not in v4 per-rule table. Default-off until calibration data lands. Backed by: Munsell, A. H. (1905), *A Color Notation*, Munsell Color Company; Itten, J. (1961), *The Art of Color*, Van Nostrand Reinhold. (Munsell color space + Itten color wheel \u2014 hue rotation analysis.)",
40189
- aiSpecific: true
40190
- },
40191
- "visual/math-rounded-entropy": {
40192
- recall: 37e-4,
40193
- fpRate: 3e-4,
40194
- ratio: 10.9,
40195
- precision: 0.9339,
40196
- lastCalibratedAt: "2026-06-27T12:00:00Z",
40197
- verdict: "USEFUL",
40198
- _calibrationNote: "v7 corpus re-calibration (2026-06-27, min-date=2025-01-01): 184488 neg + 239054 pos. USEFUL \u2014 TP=876, FP=62, P=93.4%, FPR=0.03%, lift=10.9. aiSpecific=True.",
40199
- aiSpecific: true
40200
- },
40201
- "visual/math-font-entropy": {
40202
- recall: 45e-4,
40203
- fpRate: 13e-4,
40204
- ratio: 3.32,
40205
- precision: 0.8114,
40206
- lastCalibratedAt: "2026-06-27T12:00:00Z",
40207
- verdict: "USEFUL",
40208
- _calibrationNote: "v7 corpus re-calibration (2026-06-27, min-date=2025-01-01): 184488 neg + 239054 pos. USEFUL \u2014 TP=1067, FP=248, P=81.1%, FPR=0.13%, lift=3.3. aiSpecific=True.",
40209
- aiSpecific: true
41629
+ _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.",
41630
+ aiSpecific: true,
41631
+ _v7Verdict: "OK",
41632
+ _v7Lift: 0,
41633
+ _v7Recall: 0,
41634
+ _v7FpRate: 0,
41635
+ _v7Precision: 0,
41636
+ _v8Verdict: "DORMANT",
41637
+ _v8Lift: 1,
41638
+ defaultOff: true
40210
41639
  },
40211
- "visual/math-spacing-entropy": {
40212
- recall: 18e-4,
40213
- fpRate: 6e-4,
40214
- ratio: 3.01,
40215
- precision: 0.7959,
40216
- lastCalibratedAt: "2026-06-27T12:00:00Z",
40217
- verdict: "USEFUL",
40218
- _calibrationNote: "v7 corpus re-calibration (2026-06-27, min-date=2025-01-01): 184488 neg + 239054 pos. USEFUL \u2014 TP=425, FP=109, P=79.6%, FPR=0.06%, lift=3.0. aiSpecific=True.",
40219
- aiSpecific: true
41640
+ "ai/markdown-leakage": {
41641
+ recall: 0,
41642
+ fpRate: 0,
41643
+ ratio: 10003.17,
41644
+ precision: 0.3571,
41645
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
41646
+ verdict: "OK",
41647
+ _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).",
41648
+ aiSpecific: true,
41649
+ _v7Verdict: "USEFUL",
41650
+ _v7Lift: 65504.64,
41651
+ _v7Recall: 0,
41652
+ _v7FpRate: 0,
41653
+ _v7Precision: 0.7143,
41654
+ _v8Verdict: "INVERTED",
41655
+ _v8Lift: 0
40220
41656
  },
40221
- "visual/clamp-soup": {
41657
+ "ai/renyi-profile": {
40222
41658
  recall: 0,
40223
41659
  fpRate: 0,
40224
- ratio: 0,
40225
- precision: 0,
40226
- lastCalibratedAt: "2026-06-25T00:00:00Z",
40227
- verdict: "DORMANT",
40228
- defaultOff: true,
40229
- _calibrationNote: "v0.10.1 ship \u2014 not in v4 per-rule table. Default-off until calibration data lands. Backed by: W3C (2023), CSS Values and Units Module Level 4, W3C CR-css-values-4-20231218. (W3C clamp() spec \u2014 overuse is a code-smell, not a feature.)",
40230
- aiSpecific: true
41660
+ ratio: 5251.67,
41661
+ precision: 0.25,
41662
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
41663
+ verdict: "OK",
41664
+ _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).",
41665
+ aiSpecific: true,
41666
+ _v7Verdict: "OK",
41667
+ _v7Lift: 5094.81,
41668
+ _v7Recall: 0,
41669
+ _v7FpRate: 0,
41670
+ _v7Precision: 0.25,
41671
+ _v8Verdict: "OK",
41672
+ _v8Lift: 5722.25
40231
41673
  },
40232
- "component/giant-component": {
40233
- recall: 0.0176,
40234
- fpRate: 77e-4,
40235
- ratio: 2.3,
40236
- precision: 0.7485,
40237
- lastCalibratedAt: "2026-06-27T12:00:00Z",
41674
+ "ai/segment-surprisal-cv": {
41675
+ recall: 0.2019,
41676
+ fpRate: 0.0787,
41677
+ ratio: 9.52,
41678
+ precision: 0.7495,
41679
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
40238
41680
  verdict: "USEFUL",
40239
- _calibrationNote: "v7 corpus re-calibration (2026-06-27, min-date=2025-01-01): 184488 neg + 239054 pos. USEFUL \u2014 TP=4205, FP=1413, P=74.8%, FPR=0.77%, lift=2.3. aiSpecific=True.",
40240
- aiSpecific: true
41681
+ _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).",
41682
+ aiSpecific: true,
41683
+ _v7Verdict: "USEFUL",
41684
+ _v7Lift: 9.11,
41685
+ _v7Recall: 0.1836,
41686
+ _v7FpRate: 0.0817,
41687
+ _v7Precision: 0.7438,
41688
+ _v8Verdict: "USEFUL",
41689
+ _v8Lift: 10.8
40241
41690
  },
40242
- "component/shadcn-prop-mismatch": {
40243
- recall: 13e-4,
40244
- fpRate: 1e-4,
40245
- ratio: 10.1,
40246
- precision: 0.929,
40247
- lastCalibratedAt: "2026-06-27T12:00:00Z",
41691
+ "ai/state-default-overuse": {
41692
+ recall: 3e-3,
41693
+ fpRate: 6e-4,
41694
+ ratio: 1315.06,
41695
+ precision: 0.8451,
41696
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
40248
41697
  verdict: "USEFUL",
40249
- _calibrationNote: "v7 corpus re-calibration (2026-06-27, min-date=2025-01-01): 184488 neg + 239054 pos. USEFUL \u2014 TP=314, FP=24, P=92.9%, FPR=0.01%, lift=10.1. aiSpecific=True.",
40250
- aiSpecific: true
41698
+ _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).",
41699
+ aiSpecific: true,
41700
+ _v7Verdict: "USEFUL",
41701
+ _v7Lift: 947.32,
41702
+ _v7Recall: 3e-3,
41703
+ _v7FpRate: 9e-4,
41704
+ _v7Precision: 0.8161,
41705
+ _v8Verdict: "USEFUL",
41706
+ _v8Lift: 16799.55
40251
41707
  },
40252
- "layout/math-grid-uniformity": {
40253
- recall: 3e-4,
40254
- fpRate: 2e-4,
40255
- ratio: 1.72,
40256
- precision: 0.6907,
40257
- lastCalibratedAt: "2026-06-27T12:00:00Z",
40258
- verdict: "OK",
40259
- _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.",
40260
- aiSpecific: true
40261
- },
40262
- "layout/math-element-uniformity": {
40263
- recall: 28e-4,
40264
- fpRate: 12e-4,
40265
- ratio: 2.28,
40266
- precision: 0.7475,
40267
- lastCalibratedAt: "2026-06-27T12:00:00Z",
41708
+ "ai/tailwind-color-overuse": {
41709
+ recall: 0.0264,
41710
+ fpRate: 38e-4,
41711
+ ratio: 230.97,
41712
+ precision: 0.8888,
41713
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
40268
41714
  verdict: "USEFUL",
40269
- _calibrationNote: "v7 corpus re-calibration (2026-06-27, min-date=2025-01-01): 184488 neg + 239054 pos. USEFUL \u2014 TP=666, FP=225, P=74.7%, FPR=0.12%, lift=2.3. aiSpecific=True.",
40270
- aiSpecific: true
40271
- },
40272
- "typo/math-button-label-uniformity": {
40273
- recall: 2e-4,
40274
- fpRate: 1e-4,
40275
- ratio: 1.36,
40276
- precision: 0.6379,
40277
- lastCalibratedAt: "2026-06-27T12:00:00Z",
40278
- verdict: "HYGIENE",
40279
- _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.",
40280
- aiSpecific: false
41715
+ _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).",
41716
+ aiSpecific: true,
41717
+ _v7Verdict: "USEFUL",
41718
+ _v7Lift: 161.52,
41719
+ _v7Recall: 0.0218,
41720
+ _v7FpRate: 52e-4,
41721
+ _v7Precision: 0.8436,
41722
+ _v8Verdict: "USEFUL",
41723
+ _v8Lift: 5695.79
40281
41724
  },
40282
- "perf/css-bloat": {
40283
- recall: 0.0117,
40284
- fpRate: 32e-4,
40285
- ratio: 3.64,
40286
- precision: 0.8252,
40287
- lastCalibratedAt: "2026-06-27T12:00:00Z",
40288
- verdict: "HYGIENE",
40289
- _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.",
40290
- aiSpecific: false
41725
+ "ai/text-like-ratio": {
41726
+ recall: 0,
41727
+ fpRate: 0,
41728
+ ratio: 201664,
41729
+ precision: 0.8,
41730
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
41731
+ verdict: "USEFUL",
41732
+ _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).",
41733
+ aiSpecific: true,
41734
+ _v7Verdict: "USEFUL",
41735
+ _v7Lift: 137559.75,
41736
+ _v7Recall: 0,
41737
+ _v7FpRate: 0,
41738
+ _v7Precision: 0.75,
41739
+ _v8Verdict: "USEFUL",
41740
+ _v8Lift: 99999
40291
41741
  },
40292
- "wcag/focus-appearance": {
40293
- recall: 26e-4,
40294
- fpRate: 1e-4,
40295
- ratio: 19.68,
40296
- precision: 0.9623,
40297
- lastCalibratedAt: "2026-06-27T12:00:00Z",
40298
- verdict: "HYGIENE",
40299
- _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.",
40300
- aiSpecific: false
41742
+ "ai/whitespace-regularity": {
41743
+ recall: 0.0733,
41744
+ fpRate: 0.0677,
41745
+ ratio: 8.25,
41746
+ precision: 0.5583,
41747
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
41748
+ verdict: "USEFUL",
41749
+ _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).",
41750
+ aiSpecific: true,
41751
+ _v7Verdict: "USEFUL",
41752
+ _v7Lift: 7.71,
41753
+ _v7Recall: 0.0737,
41754
+ _v7FpRate: 0.0733,
41755
+ _v7Precision: 0.5652,
41756
+ _v8Verdict: "USEFUL",
41757
+ _v8Lift: 10.06
40301
41758
  },
40302
- "wcag/target-size": {
41759
+ "arch/astro-island-leak": {
40303
41760
  recall: 0,
40304
41761
  fpRate: 0,
40305
41762
  ratio: 0,
40306
41763
  precision: 0,
40307
- lastCalibratedAt: "2026-06-25T00:00:00Z",
41764
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
40308
41765
  verdict: "DORMANT",
40309
- defaultOff: true,
40310
- _calibrationNote: "v0.10.1 ship \u2014 not in v4 per-rule table. Default-off until calibration data lands. Backed by: W3C (2018), Web Content Accessibility Guidelines (WCAG) 2.1, Success Criterion 2.5.5 (Target Size); Fitts, P. M. (1954), \u2018The Information Capacity of the Human Motor System in Controlling the Amplitude of Movement\u2019, J. Exp. Psychol. 47(6):381-391. (WCAG 2.5.5 + Fitts's Law \u2014 minimum 24\xD724 CSS px tap target.)",
40311
- aiSpecific: false
40312
- },
40313
- "component/multiple-components-per-file": {
40314
- recall: 0.0681,
40315
- fpRate: 0.052,
40316
- ratio: 1.31,
40317
- precision: 0.6294,
40318
- lastCalibratedAt: "2026-06-27T12:00:00Z",
40319
- verdict: "HYGIENE",
40320
- _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.",
40321
- aiSpecific: false
41766
+ _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.",
41767
+ aiSpecific: true,
41768
+ _v7Verdict: "DORMANT",
41769
+ _v7Lift: 0,
41770
+ _v7Recall: 0,
41771
+ _v7FpRate: 0,
41772
+ _v7Precision: 0,
41773
+ _v8Verdict: "DORMANT",
41774
+ _v8Lift: 1,
41775
+ defaultOff: true
40322
41776
  },
40323
- "context/import-path-mismatch": {
40324
- recall: 0.0739,
40325
- fpRate: 0.0228,
40326
- ratio: 3.25,
40327
- precision: 0.8079,
40328
- lastCalibratedAt: "2026-06-27T12:00:00Z",
40329
- verdict: "HYGIENE",
40330
- _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.",
40331
- aiSpecific: false
41777
+ "component/giant-component": {
41778
+ recall: 0.0181,
41779
+ fpRate: 59e-4,
41780
+ ratio: 132.31,
41781
+ precision: 0.7815,
41782
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
41783
+ verdict: "USEFUL",
41784
+ _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).",
41785
+ aiSpecific: true,
41786
+ _v7Verdict: "USEFUL",
41787
+ _v7Lift: 97.16,
41788
+ _v7Recall: 0.0177,
41789
+ _v7FpRate: 77e-4,
41790
+ _v7Precision: 0.7485,
41791
+ _v8Verdict: "USEFUL",
41792
+ _v8Lift: 846.15
40332
41793
  },
40333
- "logic/key-prop-missing": {
40334
- recall: 17e-4,
40335
- fpRate: 14e-4,
40336
- ratio: 1.28,
40337
- precision: 0.6246,
40338
- lastCalibratedAt: "2026-06-27T12:00:00Z",
40339
- verdict: "HYGIENE",
40340
- _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.",
40341
- aiSpecific: false
41794
+ "component/multiple-components-per-file": {
41795
+ recall: 0.0751,
41796
+ fpRate: 0.0423,
41797
+ ratio: 15.96,
41798
+ precision: 0.6747,
41799
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
41800
+ verdict: "USEFUL",
41801
+ _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).",
41802
+ aiSpecific: false,
41803
+ _v7Verdict: "USEFUL",
41804
+ _v7Lift: 12.04,
41805
+ _v7Recall: 0.0687,
41806
+ _v7FpRate: 0.0523,
41807
+ _v7Precision: 0.6294,
41808
+ _v8Verdict: "USEFUL",
41809
+ _v8Lift: 54.44
40342
41810
  },
40343
- "logic/math-variable-name-entropy": {
40344
- recall: 2e-4,
41811
+ "component/shadcn-prop-mismatch": {
41812
+ recall: 16e-4,
40345
41813
  fpRate: 1e-4,
40346
- ratio: 1.07,
40347
- precision: 0.5806,
40348
- lastCalibratedAt: "2026-06-27T12:00:00Z",
40349
- verdict: "HYGIENE",
40350
- _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.",
40351
- aiSpecific: false
40352
- },
40353
- "security/public-admin-route": {
40354
- recall: 28e-4,
40355
- fpRate: 78e-4,
40356
- ratio: 0.4,
40357
- precision: 0.2251,
40358
- lastCalibratedAt: "2026-06-26T22:30:00Z",
40359
- verdict: "HYGIENE",
40360
- _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]",
40361
- defaultOff: true,
40362
- aiSpecific: false
40363
- },
40364
- "security/unsafe-html-render": {
40365
- recall: 13e-4,
40366
- fpRate: 9e-4,
40367
- ratio: 1.5,
40368
- precision: 0.661,
40369
- lastCalibratedAt: "2026-06-27T12:00:00Z",
40370
- verdict: "HYGIENE",
40371
- _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.",
40372
- aiSpecific: false
40373
- },
40374
- "visual/naturalness-anomaly": {
40375
- recall: 0.1645,
40376
- fpRate: 0.0617,
40377
- ratio: 2.67,
40378
- precision: 0.7755,
40379
- lastCalibratedAt: "2026-06-27T12:00:00Z",
41814
+ ratio: 9990.98,
41815
+ precision: 0.9512,
41816
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
40380
41817
  verdict: "USEFUL",
40381
- _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.",
40382
- aiSpecific: true
41818
+ _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).",
41819
+ aiSpecific: true,
41820
+ _v7Verdict: "USEFUL",
41821
+ _v7Lift: 7099.57,
41822
+ _v7Recall: 13e-4,
41823
+ _v7FpRate: 1e-4,
41824
+ _v7Precision: 0.929,
41825
+ _v8Verdict: "USEFUL",
41826
+ _v8Lift: 99999
40383
41827
  },
40384
- "perf/halstead-anomaly": {
40385
- recall: 0,
40386
- fpRate: 0,
40387
- ratio: 2.32,
40388
- precision: 0.75,
40389
- lastCalibratedAt: "2026-06-27T12:00:00Z",
41828
+ "context/import-path-mismatch": {
41829
+ recall: 0.0681,
41830
+ fpRate: 0.0167,
41831
+ ratio: 49.48,
41832
+ precision: 0.8263,
41833
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
40390
41834
  verdict: "USEFUL",
40391
- _calibrationNote: "v7 corpus re-calibration (2026-06-27, min-date=2025-01-01): 184488 neg + 239054 pos. USEFUL \u2014 TP=3, FP=1, P=75.0%, FPR=0.00%, lift=2.3. aiSpecific=True.",
40392
- aiSpecific: true
41835
+ _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).",
41836
+ aiSpecific: false,
41837
+ _v7Verdict: "USEFUL",
41838
+ _v7Lift: 35.26,
41839
+ _v7Recall: 0.0746,
41840
+ _v7FpRate: 0.0229,
41841
+ _v7Precision: 0.8079,
41842
+ _v8Verdict: "USEFUL",
41843
+ _v8Lift: 8554.38
40393
41844
  },
40394
- "arch/astro-island-leak": {
41845
+ "db/duplicate-index": {
40395
41846
  recall: 0,
40396
41847
  fpRate: 0,
40397
41848
  ratio: 0,
40398
41849
  precision: 0,
40399
- lastCalibratedAt: "2026-06-25T00:00:00Z",
41850
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
40400
41851
  verdict: "DORMANT",
40401
- defaultOff: true,
40402
- _calibrationNote: "v0.10.1 ship \u2014 not in v4 per-rule table. Default-off until calibration data lands. Backed by: Hevery, M. (2022), \u2018Islands Architecture: A New Pattern for Server-Component Frameworks\u2019, ACM SIGPLAN International Conference on Object-Oriented Programming, Systems, Languages & Applications (OOPSLA), invited talk; Astro Documentation (2023), https://docs.astro.build. (Astro Islands architecture \u2014 client JS should not leak into server components.)",
40403
- aiSpecific: true
41852
+ _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.",
41853
+ aiSpecific: false,
41854
+ _v7Verdict: "DORMANT",
41855
+ _v7Lift: 0,
41856
+ _v7Recall: 0,
41857
+ _v7FpRate: 0,
41858
+ _v7Precision: 0,
41859
+ _v8Verdict: "DORMANT",
41860
+ _v8Lift: 1,
41861
+ defaultOff: true
40404
41862
  },
40405
- "logic/qwik-hook-leak": {
41863
+ "db/enum-sprawl": {
40406
41864
  recall: 0,
40407
41865
  fpRate: 0,
40408
41866
  ratio: 0,
40409
41867
  precision: 0,
40410
- lastCalibratedAt: "2026-06-25T00:00:00Z",
41868
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
40411
41869
  verdict: "DORMANT",
40412
- defaultOff: true,
40413
- _calibrationNote: "v0.10.1 ship \u2014 not in v4 per-rule table. Default-off until calibration data lands. Backed by: Hevery, M. (2022), \u2018Qwik: A Resumable JavaScript Framework\u2019, ACM SIGPLAN OOPSLA companion; Builder.io Technical Report. (Qwik resumability \u2014 serializing state avoids hydration cost.)",
40414
- aiSpecific: true
41870
+ _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.",
41871
+ aiSpecific: false,
41872
+ _v7Verdict: "DORMANT",
41873
+ _v7Lift: 0,
41874
+ _v7Recall: 0,
41875
+ _v7FpRate: 0,
41876
+ _v7Precision: 0,
41877
+ _v8Verdict: "DORMANT",
41878
+ _v8Lift: 1,
41879
+ defaultOff: true
40415
41880
  },
40416
- "test/missing-edge-case": {
41881
+ "db/missing-fk-index": {
40417
41882
  recall: 0,
40418
41883
  fpRate: 0,
40419
41884
  ratio: 0,
40420
41885
  precision: 0,
40421
- lastCalibratedAt: "2026-06-25T00:00:00Z",
41886
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
40422
41887
  verdict: "DORMANT",
40423
- defaultOff: true,
40424
- _calibrationNote: "v0.10.1 ship \u2014 not in v4 per-rule table. Default-off until calibration data lands. Backed by: Myers, G. J. (1979), *The Art of Software Testing*, Wiley-Interscience (canonical boundary value analysis reference); Beizer, B. (1990), *Software Testing Techniques*, 2nd ed., Van Nostrand Reinhold. (Boundary value analysis \u2014 empty / zero / max / null / type-boundary cases.)",
40425
- aiSpecific: true
41888
+ _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.",
41889
+ aiSpecific: false,
41890
+ _v7Verdict: "DORMANT",
41891
+ _v7Lift: 0,
41892
+ _v7Recall: 0,
41893
+ _v7FpRate: 0,
41894
+ _v7Precision: 0,
41895
+ _v8Verdict: "DORMANT",
41896
+ _v8Lift: 1,
41897
+ defaultOff: true
40426
41898
  },
40427
- "typo/calc-fontsize": {
41899
+ "db/missing-not-null": {
40428
41900
  recall: 0,
40429
41901
  fpRate: 0,
40430
41902
  ratio: 0,
40431
41903
  precision: 0,
40432
- lastCalibratedAt: "2026-06-25T00:00:00Z",
41904
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
40433
41905
  verdict: "DORMANT",
40434
- defaultOff: true,
40435
- _calibrationNote: "v0.10.1 ship \u2014 not in v4 per-rule table. Default-off until calibration data lands. Backed by: Marcotte, E. (2016), *Responsive Design: Patterns & Principles*, A Book Apart; Brown, J. (2018), *Every Layout*, self-published (rel='https://every-layout.dev'). (Fluid typography via clamp(min, preferred, max).)",
40436
- aiSpecific: false
41906
+ _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.",
41907
+ aiSpecific: false,
41908
+ _v7Verdict: "DORMANT",
41909
+ _v7Lift: 0,
41910
+ _v7Recall: 0,
41911
+ _v7FpRate: 0,
41912
+ _v7Precision: 0,
41913
+ _v8Verdict: "DORMANT",
41914
+ _v8Lift: 1,
41915
+ defaultOff: true
40437
41916
  },
40438
- "typo/clamp-offscale": {
41917
+ "db/naming-inconsistency": {
40439
41918
  recall: 0,
40440
41919
  fpRate: 0,
40441
41920
  ratio: 0,
40442
41921
  precision: 0,
40443
- lastCalibratedAt: "2026-06-25T00:00:00Z",
41922
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
40444
41923
  verdict: "DORMANT",
40445
- defaultOff: true,
40446
- _calibrationNote: "v0.10.1 ship \u2014 not in v4 per-rule table. Default-off until calibration data lands. Backed by: W3C (2023), CSS Values 4 \xA77.2 (Functional Notations: clamp()); Brown, J. (2018), *Every Layout*. (CSS clamp() \u2014 off-scale (negative, >10rem) values are typos.)",
40447
- aiSpecific: false
41924
+ _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.",
41925
+ aiSpecific: false,
41926
+ _v7Verdict: "DORMANT",
41927
+ _v7Lift: 0,
41928
+ _v7Recall: 0,
41929
+ _v7FpRate: 0,
41930
+ _v7Precision: 0,
41931
+ _v8Verdict: "DORMANT",
41932
+ _v8Lift: 1,
41933
+ defaultOff: true
40448
41934
  },
40449
- "typo/math-cta-vocabulary": {
41935
+ "db/sql-concat": {
41936
+ recall: 5e-4,
41937
+ fpRate: 1e-4,
41938
+ ratio: 7511.26,
41939
+ precision: 0.8343,
41940
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
41941
+ verdict: "USEFUL",
41942
+ _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).",
41943
+ aiSpecific: true,
41944
+ _v7Verdict: "DORMANT",
41945
+ _v7Lift: 1,
41946
+ _v7Recall: 0,
41947
+ _v7FpRate: 0,
41948
+ _v7Precision: 0,
41949
+ _v8Verdict: "USEFUL",
41950
+ _v8Lift: 2046.08
41951
+ },
41952
+ "dead/dead-branch": {
41953
+ recall: 2e-4,
41954
+ fpRate: 4e-4,
41955
+ ratio: 1080.68,
41956
+ precision: 0.4244,
41957
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
41958
+ verdict: "OK",
41959
+ _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.",
41960
+ aiSpecific: true,
41961
+ _v7Verdict: "DORMANT",
41962
+ _v7Lift: 1,
41963
+ _v7Recall: 0,
41964
+ _v7FpRate: 0,
41965
+ _v7Precision: 0,
41966
+ _v8Verdict: "OK",
41967
+ _v8Lift: 294.38
41968
+ },
41969
+ "dead/unreachable": {
41970
+ recall: 1e-4,
41971
+ fpRate: 6e-4,
41972
+ ratio: 153.14,
41973
+ precision: 0.0966,
41974
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
41975
+ verdict: "OK",
41976
+ _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.",
41977
+ aiSpecific: true,
41978
+ _v7Verdict: "DORMANT",
41979
+ _v7Lift: 1,
41980
+ _v7Recall: 0,
41981
+ _v7FpRate: 0,
41982
+ _v7Precision: 0,
41983
+ _v8Verdict: "OK",
41984
+ _v8Lift: 41.71
41985
+ },
41986
+ "dead/unused-import": {
41987
+ recall: 0.0379,
41988
+ fpRate: 0.0222,
41989
+ ratio: 30.06,
41990
+ precision: 0.6662,
41991
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
41992
+ verdict: "USEFUL",
41993
+ _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.",
41994
+ aiSpecific: true,
41995
+ _v7Verdict: "DORMANT",
41996
+ _v7Lift: 1,
41997
+ _v7Recall: 0,
41998
+ _v7FpRate: 0,
41999
+ _v7Precision: 0,
42000
+ _v8Verdict: "USEFUL",
42001
+ _v8Lift: 8.19
42002
+ },
42003
+ "dead/unused-local": {
42004
+ recall: 0.0477,
42005
+ fpRate: 74e-4,
42006
+ ratio: 120.18,
42007
+ precision: 0.8834,
42008
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
42009
+ verdict: "USEFUL",
42010
+ _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.",
42011
+ aiSpecific: true,
42012
+ _v7Verdict: "DORMANT",
42013
+ _v7Lift: 1,
42014
+ _v7Recall: 0,
42015
+ _v7FpRate: 0,
42016
+ _v7Precision: 0,
42017
+ _v8Verdict: "USEFUL",
42018
+ _v8Lift: 32.74
42019
+ },
42020
+ "dead/unused-parameter": {
42021
+ recall: 8e-4,
42022
+ fpRate: 27e-4,
42023
+ ratio: 98,
42024
+ precision: 0.2628,
42025
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
42026
+ verdict: "OK",
42027
+ _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.",
42028
+ aiSpecific: true,
42029
+ _v7Verdict: "DORMANT",
42030
+ _v7Lift: 1,
42031
+ _v7Recall: 0,
42032
+ _v7FpRate: 0,
42033
+ _v7Precision: 0,
42034
+ _v8Verdict: "OK",
42035
+ _v8Lift: 26.7
42036
+ },
42037
+ "docs/broken-link": {
42038
+ recall: 14e-4,
42039
+ fpRate: 23e-4,
42040
+ ratio: 178.13,
42041
+ precision: 0.4155,
42042
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
42043
+ verdict: "OK",
42044
+ _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).",
42045
+ aiSpecific: false,
42046
+ _v7Verdict: "DORMANT",
42047
+ _v7Lift: 1,
42048
+ _v7Recall: 0,
42049
+ _v7FpRate: 0,
42050
+ _v7Precision: 0,
42051
+ _v8Verdict: "OK",
42052
+ _v8Lift: 48.52
42053
+ },
42054
+ "docs/expired-code-example": {
40450
42055
  recall: 0,
40451
42056
  fpRate: 0,
40452
42057
  ratio: 0,
40453
42058
  precision: 0,
40454
- lastCalibratedAt: "2026-06-25T00:00:00Z",
40455
- verdict: "DORMANT",
40456
- defaultOff: true,
40457
- _calibrationNote: "v0.10.1 ship \u2014 not in v4 per-rule table. Default-off until calibration data lands. Backed by: Cialdini, R. B. (1984), *Influence: The Psychology of Persuasion*, Harper Business; Krug, S. (2000), *Don't Make Me Think*, 2nd ed., New Riders. (CTA wording \u2014 vague labels reduce click-through per Cialdini commitment/consistency.)",
40458
- aiSpecific: true
42059
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
42060
+ verdict: "INVERTED",
42061
+ _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).",
42062
+ aiSpecific: false,
42063
+ _v7Verdict: "DORMANT",
42064
+ _v7Lift: 1,
42065
+ _v7Recall: 0,
42066
+ _v7FpRate: 0,
42067
+ _v7Precision: 0,
42068
+ _v8Verdict: "INVERTED",
42069
+ _v8Lift: 0,
42070
+ defaultOff: true
42071
+ },
42072
+ "docs/stale-function-reference": {
42073
+ recall: 26e-4,
42074
+ fpRate: 5e-4,
42075
+ ratio: 1638.47,
42076
+ precision: 0.8515,
42077
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
42078
+ verdict: "USEFUL",
42079
+ _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).",
42080
+ aiSpecific: false,
42081
+ _v7Verdict: "DORMANT",
42082
+ _v7Lift: 1,
42083
+ _v7Recall: 0,
42084
+ _v7FpRate: 0,
42085
+ _v7Precision: 0,
42086
+ _v8Verdict: "USEFUL",
42087
+ _v8Lift: 446.32
42088
+ },
42089
+ "docs/stale-package-reference": {
42090
+ recall: 2e-4,
42091
+ fpRate: 4e-4,
42092
+ ratio: 939.43,
42093
+ precision: 0.3429,
42094
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
42095
+ verdict: "OK",
42096
+ _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).",
42097
+ aiSpecific: false,
42098
+ _v7Verdict: "DORMANT",
42099
+ _v7Lift: 1,
42100
+ _v7Recall: 0,
42101
+ _v7FpRate: 0,
42102
+ _v7Precision: 0,
42103
+ _v8Verdict: "OK",
42104
+ _v8Lift: 255.9
40459
42105
  },
40460
42106
  "layout/forced-layout": {
40461
42107
  recall: 0,
40462
42108
  fpRate: 0,
40463
42109
  ratio: 0,
40464
42110
  precision: 0,
40465
- lastCalibratedAt: "2026-06-25T00:00:00Z",
42111
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
40466
42112
  verdict: "DORMANT",
40467
- defaultOff: true,
40468
- _calibrationNote: "v0.10.1 ship \u2014 not in v4 per-rule table. Default-off until calibration data lands. Backed by: Mozilla Developer Network (2023), CSS Grid Layout, https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_grid_layout; W3C (2023), CSS Grid Layout Module Level 3, W3C CR-css-grid-3-20231218. (CSS Grid spec \u2014 forced layout is a fallback hack, not the idiomatic approach.)",
40469
- aiSpecific: true
42113
+ _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.",
42114
+ aiSpecific: true,
42115
+ _v7Verdict: "DORMANT",
42116
+ _v7Lift: 0,
42117
+ _v7Recall: 0,
42118
+ _v7FpRate: 0,
42119
+ _v7Precision: 0,
42120
+ _v8Verdict: "DORMANT",
42121
+ _v8Lift: 1,
42122
+ defaultOff: true
40470
42123
  },
40471
- "visual/generic-centering": {
42124
+ "layout/gap-monopoly": {
42125
+ recall: 3e-4,
42126
+ fpRate: 1e-4,
42127
+ ratio: 8859.33,
42128
+ precision: 0.8083,
42129
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
42130
+ verdict: "USEFUL",
42131
+ _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).",
42132
+ aiSpecific: false,
42133
+ _v7Verdict: "USEFUL",
42134
+ _v7Lift: 6322.11,
42135
+ _v7Recall: 4e-4,
42136
+ _v7FpRate: 1e-4,
42137
+ _v7Precision: 0.7928,
42138
+ _v8Verdict: "USEFUL",
42139
+ _v8Lift: 99999
42140
+ },
42141
+ "layout/math-element-uniformity": {
42142
+ recall: 29e-4,
42143
+ fpRate: 1e-3,
42144
+ ratio: 770.74,
42145
+ precision: 0.7705,
42146
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
42147
+ verdict: "USEFUL",
42148
+ _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).",
42149
+ aiSpecific: true,
42150
+ _v7Verdict: "USEFUL",
42151
+ _v7Lift: 609.32,
42152
+ _v7Recall: 28e-4,
42153
+ _v7FpRate: 12e-4,
42154
+ _v7Precision: 0.7475,
42155
+ _v8Verdict: "USEFUL",
42156
+ _v8Lift: 2211.5
42157
+ },
42158
+ "layout/math-grid-uniformity": {
42159
+ recall: 3e-4,
42160
+ fpRate: 1e-4,
42161
+ ratio: 5839.98,
42162
+ precision: 0.7182,
42163
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
42164
+ verdict: "USEFUL",
42165
+ _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).",
42166
+ aiSpecific: true,
42167
+ _v7Verdict: "USEFUL",
42168
+ _v7Lift: 4222.91,
42169
+ _v7Recall: 3e-4,
42170
+ _v7FpRate: 2e-4,
42171
+ _v7Precision: 0.6907,
42172
+ _v8Verdict: "USEFUL",
42173
+ _v8Lift: 63384.92
42174
+ },
42175
+ "layout/spacing-grid": {
42176
+ recall: 2e-4,
42177
+ fpRate: 2e-4,
42178
+ ratio: 4051.29,
42179
+ precision: 0.6429,
42180
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
42181
+ verdict: "USEFUL",
42182
+ _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).",
42183
+ aiSpecific: false,
42184
+ _v7Verdict: "USEFUL",
42185
+ _v7Lift: 8831,
42186
+ _v7Recall: 2e-4,
42187
+ _v7FpRate: 1e-4,
42188
+ _v7Precision: 0.7222,
42189
+ _v8Verdict: "USEFUL",
42190
+ _v8Lift: 1562.77
42191
+ },
42192
+ "logic/bayesian-conditional": {
40472
42193
  recall: 0,
40473
42194
  fpRate: 0,
40474
42195
  ratio: 0,
40475
42196
  precision: 0,
40476
- lastCalibratedAt: "2026-06-25T00:00:00Z",
42197
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
40477
42198
  verdict: "DORMANT",
40478
- defaultOff: true,
40479
- _calibrationNote: "v0.10.1 ship \u2014 not in v4 per-rule table. Default-off until calibration data lands. Backed by: Wertheimer, M. (1923), \u2018Untersuchungen zur Lehre von der Gestalt II\u2019, Psychologische Forschung 4:301-350; M\xFCller-Brockmann, J. (1981), *Grid Systems in Graphic Design*, Niggli. (Gestalt centering + grid systems \u2014 generic centering is anti-grid.)",
40480
- aiSpecific: true
42199
+ _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.",
42200
+ aiSpecific: true,
42201
+ _v7Verdict: "DORMANT",
42202
+ _v7Lift: 0,
42203
+ _v7Recall: 0,
42204
+ _v7FpRate: 0,
42205
+ _v7Precision: 0,
42206
+ _v8Verdict: "DORMANT",
42207
+ _v8Lift: 1,
42208
+ defaultOff: true
40481
42209
  },
40482
- "product/terminology-drift": {
40483
- recall: 85e-4,
40484
- fpRate: 28e-4,
40485
- ratio: 3,
40486
- precision: 0.7956,
40487
- lastCalibratedAt: "2026-06-27T12:00:00Z",
40488
- verdict: "HYGIENE",
40489
- _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.",
40490
- aiSpecific: false
42210
+ "logic/boundary-violation": {
42211
+ recall: 0.0274,
42212
+ fpRate: 0.0137,
42213
+ ratio: 51.32,
42214
+ precision: 0.7006,
42215
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
42216
+ verdict: "USEFUL",
42217
+ _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).",
42218
+ aiSpecific: false,
42219
+ _v7Verdict: "USEFUL",
42220
+ _v7Lift: 37.42,
42221
+ _v7Recall: 0.0265,
42222
+ _v7FpRate: 0.0176,
42223
+ _v7Precision: 0.6601,
42224
+ _v8Verdict: "USEFUL",
42225
+ _v8Lift: 298.57
40491
42226
  },
40492
- "product/ux-pattern-fragmentation": {
42227
+ "logic/ghost-defensive": {
40493
42228
  recall: 1e-4,
40494
42229
  fpRate: 0,
40495
- ratio: 3.09,
40496
- precision: 0.8,
40497
- lastCalibratedAt: "2026-06-27T12:00:00Z",
42230
+ ratio: 112035.56,
42231
+ precision: 0.8889,
42232
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
40498
42233
  verdict: "USEFUL",
40499
- _calibrationNote: "v7 corpus re-calibration (2026-06-27, min-date=2025-01-01): 184488 neg + 239054 pos. USEFUL \u2014 TP=32, FP=8, P=80.0%, FPR=0.00%, lift=3.1. aiSpecific=True.",
40500
- aiSpecific: true
42234
+ _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).",
42235
+ aiSpecific: true,
42236
+ _v7Verdict: "USEFUL",
42237
+ _v7Lift: 80917.5,
42238
+ _v7Recall: 1e-4,
42239
+ _v7FpRate: 0,
42240
+ _v7Precision: 0.8824,
42241
+ _v8Verdict: "USEFUL",
42242
+ _v8Lift: 99999
40501
42243
  },
40502
- "security/sql-construction": {
40503
- recall: 3e-3,
40504
- fpRate: 18e-4,
40505
- ratio: 1.63,
40506
- precision: 0.6788,
40507
- lastCalibratedAt: "2026-06-27T12:00:00Z",
42244
+ "logic/heaps-deviation": {
42245
+ recall: 0.0126,
42246
+ fpRate: 0.0178,
42247
+ ratio: 25.54,
42248
+ precision: 0.4536,
42249
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
40508
42250
  verdict: "OK",
40509
- _calibrationNote: "v7 corpus re-calibration (2026-06-27, min-date=2025-01-01): 184488 neg + 239054 pos. OK \u2014 TP=710, FP=336, P=67.9%, FPR=0.18%, lift=1.6. aiSpecific=True.",
40510
- aiSpecific: true
42251
+ _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).",
42252
+ aiSpecific: false,
42253
+ _v7Verdict: "USEFUL",
42254
+ _v7Lift: 41.22,
42255
+ _v7Recall: 0.0123,
42256
+ _v7FpRate: 0.0132,
42257
+ _v7Precision: 0.5461,
42258
+ _v8Verdict: "OK",
42259
+ _v8Lift: 9.36
40511
42260
  },
40512
- "security/missing-auth-check": {
40513
- recall: 63e-4,
40514
- fpRate: 4e-4,
40515
- ratio: 15.3,
40516
- precision: 0.9247,
40517
- lastCalibratedAt: "2026-06-26T22:30:00Z",
42261
+ "logic/key-prop-missing": {
42262
+ recall: 16e-4,
42263
+ fpRate: 11e-4,
42264
+ ratio: 574.52,
42265
+ precision: 0.629,
42266
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
40518
42267
  verdict: "USEFUL",
40519
- _calibrationNote: "v4 corpus (2026-06-25): 95,599 neg + 76,550 pos (frontend, TS/TSX/JS/JSX). USEFUL \u2014 TP=479, FP=39, P=92.5%, FPR=0.04%, lift=15.3.",
40520
- aiSpecific: false
42268
+ _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).",
42269
+ aiSpecific: false,
42270
+ _v7Verdict: "USEFUL",
42271
+ _v7Lift: 458.26,
42272
+ _v7Recall: 18e-4,
42273
+ _v7FpRate: 14e-4,
42274
+ _v7Precision: 0.6246,
42275
+ _v8Verdict: "USEFUL",
42276
+ _v8Lift: 1760.69
40521
42277
  },
40522
- "security/dangerous-cors": {
40523
- recall: 5e-4,
40524
- fpRate: 5e-4,
40525
- ratio: 1.05,
40526
- precision: 0.5758,
40527
- lastCalibratedAt: "2026-06-27T12:00:00Z",
42278
+ "logic/ks-distribution-shift": {
42279
+ recall: 0.6889,
42280
+ fpRate: 0.4411,
42281
+ ratio: 1.46,
42282
+ precision: 0.6457,
42283
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
40528
42284
  verdict: "NOISY",
40529
- _calibrationNote: "v7 corpus re-calibration (2026-06-27, min-date=2025-01-01): 184488 neg + 239054 pos. NOISY \u2014 TP=114, FP=84, P=57.6%, FPR=0.05%, lift=1.0. aiSpecific=True.",
40530
- defaultOff: true,
40531
- aiSpecific: true
40532
- },
40533
- "test/duplicate-setup": {
40534
- recall: 1e-4,
40535
- fpRate: 0,
40536
- ratio: 3.6,
40537
- precision: 0.8235,
40538
- lastCalibratedAt: "2026-06-27T12:00:00Z",
40539
- verdict: "USEFUL",
40540
- _calibrationNote: "v7 corpus re-calibration (2026-06-27, min-date=2025-01-01): 184488 neg + 239054 pos. USEFUL \u2014 TP=14, FP=3, P=82.4%, FPR=0.00%, lift=3.6. aiSpecific=True.",
40541
- aiSpecific: true
40542
- },
40543
- "logic/ghost-defensive": {
40544
- recall: 1e-4,
40545
- fpRate: 0,
40546
- ratio: 5.79,
40547
- precision: 0.8824,
40548
- lastCalibratedAt: "2026-06-27T12:00:00Z",
40549
- verdict: "USEFUL",
40550
- _calibrationNote: "v7 corpus re-calibration (2026-06-27, min-date=2025-01-01): 184488 neg + 239054 pos. USEFUL \u2014 TP=15, FP=2, P=88.2%, FPR=0.00%, lift=5.8. aiSpecific=True.",
40551
- aiSpecific: true
40552
- },
40553
- "typo/calc-raw-px": {
40554
- recall: 0,
40555
- fpRate: 0,
40556
- ratio: 2.32,
40557
- precision: 0.75,
40558
- lastCalibratedAt: "2026-06-27T12:00:00Z",
40559
- verdict: "HYGIENE",
40560
- _calibrationNote: "v7 corpus re-calibration (2026-06-27, min-date=2025-01-01): 184488 neg + 239054 pos. HYGIENE \u2014 TP=3, FP=1, P=75.0%, FPR=0.00%, lift=2.3. aiSpecific=False.",
40561
- aiSpecific: false
42285
+ _calibrationNote: "v8.5 calibration (v0.18.9, 2026-07-01): v7+v8 combined corpus (252080 neg + 294178 pos). v8.5 TP=202658, FP=111193, P=64.6%, FPR=44.11%, lift=1.46. v7 was USEFUL (TP=152391, FP=62358, lift=2.09). v8 was INVERTED (TP=50267, FP=48835).",
42286
+ aiSpecific: false,
42287
+ _v7Verdict: "USEFUL",
42288
+ _v7Lift: 2.09,
42289
+ _v7Recall: 0.6431,
42290
+ _v7FpRate: 0.34,
42291
+ _v7Precision: 0.7096,
42292
+ _v8Verdict: "INVERTED",
42293
+ _v8Lift: 0.71,
42294
+ defaultOff: true
40562
42295
  },
40563
- "security/fail-open-auth": {
40564
- recall: 0,
40565
- fpRate: 0,
40566
- ratio: 99.99,
40567
- precision: 1,
40568
- lastCalibratedAt: "2026-06-27T12:00:00Z",
42296
+ "logic/math-any-density": {
42297
+ recall: 17e-4,
42298
+ fpRate: 13e-4,
42299
+ ratio: 464.59,
42300
+ precision: 0.6027,
42301
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
40569
42302
  verdict: "USEFUL",
40570
- _calibrationNote: "v7 corpus re-calibration (2026-06-27, min-date=2025-01-01): 184488 neg + 239054 pos. USEFUL \u2014 TP=1, FP=0, P=100.0%, FPR=0.00%, lift=inf. aiSpecific=True.",
40571
- aiSpecific: true
42303
+ _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).",
42304
+ aiSpecific: true,
42305
+ _v7Verdict: "USEFUL",
42306
+ _v7Lift: 448.16,
42307
+ _v7Recall: 16e-4,
42308
+ _v7FpRate: 13e-4,
42309
+ _v7Precision: 0.6035,
42310
+ _v8Verdict: "USEFUL",
42311
+ _v8Lift: 515
40572
42312
  },
40573
- "wcag/focus-obscured": {
40574
- recall: 33e-4,
40575
- fpRate: 9e-4,
40576
- ratio: 3.51,
40577
- precision: 0.82,
40578
- lastCalibratedAt: "2026-06-27T12:00:00Z",
40579
- verdict: "HYGIENE",
40580
- _calibrationNote: "v7 corpus re-calibration (2026-06-27, min-date=2025-01-01): 184488 neg + 239054 pos. HYGIENE \u2014 TP=797, FP=175, P=82.0%, FPR=0.09%, lift=3.5. aiSpecific=False.",
40581
- aiSpecific: false
40582
- },
40583
- "visual/arbitrary-escape": {
40584
- recall: 25e-4,
40585
- fpRate: 9e-4,
40586
- ratio: 2.74,
40587
- precision: 0.7802,
40588
- lastCalibratedAt: "2026-06-27T12:00:00Z",
42313
+ "logic/math-console-log-storm": {
42314
+ recall: 65e-4,
42315
+ fpRate: 11e-4,
42316
+ ratio: 794.4,
42317
+ precision: 0.8729,
42318
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
40589
42319
  verdict: "USEFUL",
40590
- _calibrationNote: "v7 corpus re-calibration (2026-06-27, min-date=2025-01-01): 184488 neg + 239054 pos. USEFUL \u2014 TP=600, FP=169, P=78.0%, FPR=0.09%, lift=2.7. aiSpecific=True.",
40591
- aiSpecific: true
42320
+ _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).",
42321
+ aiSpecific: true,
42322
+ _v7Verdict: "USEFUL",
42323
+ _v7Lift: 852.3,
42324
+ _v7Recall: 71e-4,
42325
+ _v7FpRate: 11e-4,
42326
+ _v7Precision: 0.8968,
42327
+ _v8Verdict: "USEFUL",
42328
+ _v8Lift: 595.24
40592
42329
  },
40593
- "security/hardcoded-secret": {
42330
+ "logic/math-gini-class-usage": {
40594
42331
  recall: 13e-4,
40595
- fpRate: 7e-4,
40596
- ratio: 1.72,
40597
- precision: 0.6899,
40598
- lastCalibratedAt: "2026-06-27T12:00:00Z",
40599
- verdict: "OK",
40600
- _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.",
40601
- aiSpecific: true
40602
- },
40603
- "visual/radius-scale-violation": {
40604
- recall: 4e-4,
40605
- fpRate: 0,
40606
- ratio: 24.7,
40607
- precision: 0.9697,
40608
- lastCalibratedAt: "2026-06-27T12:00:00Z",
40609
- verdict: "HYGIENE",
40610
- _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.",
40611
- aiSpecific: false
40612
- },
40613
- "test/fake-placeholder": {
40614
- recall: 53e-4,
40615
- fpRate: 19e-4,
40616
- ratio: 2.82,
40617
- precision: 0.7854,
40618
- lastCalibratedAt: "2026-06-27T12:00:00Z",
42332
+ fpRate: 2e-4,
42333
+ ratio: 4648.6,
42334
+ precision: 0.8852,
42335
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
40619
42336
  verdict: "USEFUL",
40620
- _calibrationNote: "v7 corpus re-calibration (2026-06-27, min-date=2025-01-01): 184488 neg + 239054 pos. USEFUL \u2014 TP=1259, FP=344, P=78.5%, FPR=0.19%, lift=2.8. aiSpecific=True.",
40621
- aiSpecific: true
40622
- },
40623
- "security/exposed-env-var": {
40624
- recall: 6e-4,
40625
- fpRate: 7e-4,
40626
- ratio: 0.9,
40627
- precision: 0.5387,
40628
- lastCalibratedAt: "2026-06-27T12:00:00Z",
40629
- verdict: "HYGIENE",
40630
- _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.",
40631
- aiSpecific: false
40632
- },
40633
- "perf/cls-image": {
40634
- recall: 2e-4,
40635
- fpRate: 3e-4,
40636
- ratio: 0.8,
40637
- precision: 0.5104,
40638
- lastCalibratedAt: "2026-06-27T12:00:00Z",
40639
- verdict: "HYGIENE",
40640
- _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.",
40641
- aiSpecific: false
40642
- },
40643
- "layout/gap-monopoly": {
40644
- recall: 4e-4,
40645
- fpRate: 1e-4,
40646
- ratio: 2.95,
40647
- precision: 0.7928,
40648
- lastCalibratedAt: "2026-06-27T12:00:00Z",
40649
- verdict: "HYGIENE",
40650
- _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.",
40651
- aiSpecific: false
40652
- },
40653
- "visual/spacing-scale-violation": {
40654
- recall: 83e-4,
40655
- fpRate: 39e-4,
40656
- ratio: 2.13,
40657
- precision: 0.7342,
40658
- lastCalibratedAt: "2026-06-27T12:00:00Z",
40659
- verdict: "HYGIENE",
40660
- _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.",
40661
- aiSpecific: false
40662
- },
40663
- "visual/inline-style-dominance": {
40664
- recall: 96e-4,
40665
- fpRate: 66e-4,
40666
- ratio: 1.46,
40667
- precision: 0.6535,
40668
- lastCalibratedAt: "2026-06-27T12:00:00Z",
40669
- verdict: "HYGIENE",
40670
- _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.",
40671
- aiSpecific: false
42337
+ _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).",
42338
+ aiSpecific: true,
42339
+ _v7Verdict: "USEFUL",
42340
+ _v7Lift: 3388.64,
42341
+ _v7Recall: 13e-4,
42342
+ _v7FpRate: 3e-4,
42343
+ _v7Precision: 0.8683,
42344
+ _v8Verdict: "USEFUL",
42345
+ _v8Lift: 67541.31
40672
42346
  },
40673
- "layout/spacing-grid": {
42347
+ "logic/math-variable-name-entropy": {
40674
42348
  recall: 2e-4,
40675
42349
  fpRate: 1e-4,
40676
- ratio: 2.01,
40677
- precision: 0.7222,
40678
- lastCalibratedAt: "2026-06-27T12:00:00Z",
40679
- verdict: "HYGIENE",
40680
- _calibrationNote: "v7 corpus re-calibration (2026-06-27, min-date=2025-01-01): 184488 neg + 239054 pos. HYGIENE \u2014 TP=39, FP=15, P=72.2%, FPR=0.01%, lift=2.0. aiSpecific=False.",
40681
- aiSpecific: false
40682
- },
40683
- "wcag/dragging-movements": {
40684
- recall: 0,
40685
- fpRate: 0,
40686
- ratio: 0.51,
40687
- precision: 0.4,
40688
- lastCalibratedAt: "2026-06-27T12:00:00Z",
40689
- verdict: "HYGIENE",
40690
- _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.",
40691
- aiSpecific: false
42350
+ ratio: 4548.81,
42351
+ precision: 0.6316,
42352
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
42353
+ verdict: "USEFUL",
42354
+ _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).",
42355
+ aiSpecific: false,
42356
+ _v7Verdict: "USEFUL",
42357
+ _v7Lift: 4096.07,
42358
+ _v7Recall: 2e-4,
42359
+ _v7FpRate: 1e-4,
42360
+ _v7Precision: 0.5806,
42361
+ _v8Verdict: "USEFUL",
42362
+ _v8Lift: 5548.85
40692
42363
  },
40693
- "test/weak-assertion": {
40694
- recall: 0.0414,
40695
- fpRate: 86e-4,
40696
- ratio: 4.83,
40697
- precision: 0.8622,
40698
- lastCalibratedAt: "2026-06-27T12:00:00Z",
42364
+ "logic/optimistic-no-rollback": {
42365
+ recall: 12e-4,
42366
+ fpRate: 2e-4,
42367
+ ratio: 3523.57,
42368
+ precision: 0.8527,
42369
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
40699
42370
  verdict: "USEFUL",
40700
- _calibrationNote: "v7 corpus re-calibration (2026-06-27, min-date=2025-01-01): 184488 neg + 239054 pos. USEFUL \u2014 TP=9906, FP=1583, P=86.2%, FPR=0.86%, lift=4.8. aiSpecific=True.",
40701
- aiSpecific: true
42371
+ _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).",
42372
+ aiSpecific: true,
42373
+ _v7Verdict: "USEFUL",
42374
+ _v7Lift: 2519.02,
42375
+ _v7Recall: 12e-4,
42376
+ _v7FpRate: 3e-4,
42377
+ _v7Precision: 0.824,
42378
+ _v8Verdict: "USEFUL",
42379
+ _v8Lift: 67726.36
40702
42380
  },
40703
- "logic/bayesian-conditional": {
42381
+ "logic/qwik-hook-leak": {
40704
42382
  recall: 0,
40705
42383
  fpRate: 0,
40706
42384
  ratio: 0,
40707
42385
  precision: 0,
40708
- lastCalibratedAt: "2026-06-27T00:00:00Z",
42386
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
40709
42387
  verdict: "DORMANT",
40710
- defaultOff: true,
40711
- _calibrationNote: "v0.12.0 ship \u2014 new Bayesian LR-combiner rule (Bento et al. 2024 *Neurocomputing*). Default-off until v0.12 corpus re-calibration lands. Threshold P(AI|fires) \u2265 0.7; posterior computed from per-rule likelihood ratios.",
40712
- aiSpecific: true
42388
+ _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.",
42389
+ aiSpecific: true,
42390
+ _v7Verdict: "DORMANT",
42391
+ _v7Lift: 0,
42392
+ _v7Recall: 0,
42393
+ _v7FpRate: 0,
42394
+ _v7Precision: 0,
42395
+ _v8Verdict: "DORMANT",
42396
+ _v8Lift: 1,
42397
+ defaultOff: true
40713
42398
  },
40714
- "logic/heaps-deviation": {
40715
- recall: 0.0122,
40716
- fpRate: 0.0132,
40717
- ratio: 0.93,
40718
- precision: 0.5461,
40719
- lastCalibratedAt: "2026-06-27T12:00:00Z",
40720
- verdict: "HYGIENE",
40721
- _calibrationNote: "v7 corpus re-calibration (2026-06-27, min-date=2025-01-01): 184488 neg + 239054 pos. HYGIENE \u2014 TP=2924, FP=2430, P=54.6%, FPR=1.32%, lift=0.9. aiSpecific=False.",
40722
- aiSpecific: false
40723
- },
40724
- "logic/ks-distribution-shift": {
40725
- recall: 0.6375,
40726
- fpRate: 0.338,
40727
- ratio: 1.89,
40728
- precision: 0.7096,
40729
- lastCalibratedAt: "2026-06-27T12:00:00Z",
40730
- verdict: "HYGIENE",
40731
- _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.",
40732
- aiSpecific: false
42399
+ "logic/reactive-hook-soup": {
42400
+ recall: 41e-4,
42401
+ fpRate: 6e-4,
42402
+ ratio: 1370.15,
42403
+ precision: 0.8805,
42404
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
42405
+ verdict: "USEFUL",
42406
+ _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).",
42407
+ aiSpecific: true,
42408
+ _v7Verdict: "USEFUL",
42409
+ _v7Lift: 959.64,
42410
+ _v7Recall: 38e-4,
42411
+ _v7FpRate: 9e-4,
42412
+ _v7Precision: 0.8476,
42413
+ _v8Verdict: "USEFUL",
42414
+ _v8Lift: 99999
40733
42415
  },
40734
42416
  "logic/zipf-slope-anomaly": {
40735
- recall: 0.0156,
40736
- fpRate: 87e-4,
40737
- ratio: 1.79,
40738
- precision: 0.6983,
40739
- lastCalibratedAt: "2026-06-27T12:00:00Z",
40740
- verdict: "HYGIENE",
40741
- _calibrationNote: "v7 corpus re-calibration (2026-06-27, min-date=2025-01-01): 184488 neg + 239054 pos. HYGIENE \u2014 TP=3718, FP=1606, P=69.8%, FPR=0.87%, lift=1.8. aiSpecific=False.",
40742
- aiSpecific: false
42417
+ recall: 0.0168,
42418
+ fpRate: 0.0111,
42419
+ ratio: 57.13,
42420
+ precision: 0.6369,
42421
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
42422
+ verdict: "USEFUL",
42423
+ _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).",
42424
+ aiSpecific: false,
42425
+ _v7Verdict: "USEFUL",
42426
+ _v7Lift: 79.75,
42427
+ _v7Recall: 0.0157,
42428
+ _v7FpRate: 88e-4,
42429
+ _v7Precision: 0.6983,
42430
+ _v8Verdict: "USEFUL",
42431
+ _v8Lift: 28.59
40743
42432
  },
40744
- "ai/markdown-leakage": {
40745
- recall: 0,
42433
+ "logic/zombie-state": {
42434
+ recall: 1e-4,
40746
42435
  fpRate: 0,
40747
- ratio: 1.93,
40748
- precision: 0.7143,
40749
- lastCalibratedAt: "2026-06-27T12:00:00Z",
40750
- verdict: "OK",
40751
- _calibrationNote: "v7 corpus re-calibration (2026-06-27, min-date=2025-01-01): 184488 neg + 239054 pos. OK \u2014 TP=5, FP=2, P=71.4%, FPR=0.00%, lift=1.9. aiSpecific=True.",
40752
- aiSpecific: true
42436
+ ratio: 119891.71,
42437
+ precision: 0.9512,
42438
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
42439
+ verdict: "USEFUL",
42440
+ _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).",
42441
+ aiSpecific: true,
42442
+ _v7Verdict: "USEFUL",
42443
+ _v7Lift: 84652.15,
42444
+ _v7Recall: 1e-4,
42445
+ _v7FpRate: 0,
42446
+ _v7Precision: 0.9231,
42447
+ _v8Verdict: "USEFUL",
42448
+ _v8Lift: 99999
40753
42449
  },
40754
- "ai/comment-ratio": {
40755
- recall: 0.2523,
40756
- fpRate: 0.1619,
40757
- ratio: 1.56,
40758
- precision: 0.6687,
40759
- lastCalibratedAt: "2026-06-27T12:00:00Z",
40760
- verdict: "OK",
40761
- _calibrationNote: "v7 corpus re-calibration (2026-06-27, min-date=2025-01-01): 184488 neg + 239054 pos. OK \u2014 TP=60308, FP=29876, P=66.9%, FPR=16.19%, lift=1.6. aiSpecific=True.",
40762
- aiSpecific: true
42450
+ "perf/cls-image": {
42451
+ recall: 2e-4,
42452
+ fpRate: 2e-4,
42453
+ ratio: 2895.78,
42454
+ precision: 0.5514,
42455
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
42456
+ verdict: "USEFUL",
42457
+ _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).",
42458
+ aiSpecific: false,
42459
+ _v7Verdict: "USEFUL",
42460
+ _v7Lift: 1991.85,
42461
+ _v7Recall: 2e-4,
42462
+ _v7FpRate: 3e-4,
42463
+ _v7Precision: 0.5104,
42464
+ _v8Verdict: "USEFUL",
42465
+ _v8Lift: 62424.55
40763
42466
  },
40764
- "ai/whitespace-regularity": {
40765
- recall: 0.0731,
40766
- fpRate: 0.0728,
40767
- ratio: 1,
40768
- precision: 0.5652,
40769
- lastCalibratedAt: "2026-06-27T12:00:00Z",
40770
- verdict: "NOISY",
40771
- _calibrationNote: "v7 corpus re-calibration (2026-06-27, min-date=2025-01-01): 184488 neg + 239054 pos. NOISY \u2014 TP=17466, FP=13438, P=56.5%, FPR=7.28%, lift=1.0. aiSpecific=True.",
40772
- defaultOff: true,
40773
- aiSpecific: true
42467
+ "perf/css-bloat": {
42468
+ recall: 0.0126,
42469
+ fpRate: 24e-4,
42470
+ ratio: 365.63,
42471
+ precision: 0.8616,
42472
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
42473
+ verdict: "USEFUL",
42474
+ _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).",
42475
+ aiSpecific: false,
42476
+ _v7Verdict: "USEFUL",
42477
+ _v7Lift: 256.1,
42478
+ _v7Recall: 0.0118,
42479
+ _v7FpRate: 32e-4,
42480
+ _v7Precision: 0.8252,
42481
+ _v8Verdict: "USEFUL",
42482
+ _v8Lift: 22813.54
40774
42483
  },
40775
- "ai/text-like-ratio": {
42484
+ "perf/halstead-anomaly": {
40776
42485
  recall: 0,
40777
42486
  fpRate: 0,
40778
- ratio: 2.32,
40779
- precision: 0.75,
40780
- lastCalibratedAt: "2026-06-27T12:00:00Z",
42487
+ ratio: 75624,
42488
+ precision: 0.6,
42489
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
40781
42490
  verdict: "USEFUL",
40782
- _calibrationNote: "v7 corpus re-calibration (2026-06-27, min-date=2025-01-01): 184488 neg + 239054 pos. USEFUL \u2014 TP=3, FP=1, P=75.0%, FPR=0.00%, lift=2.3. aiSpecific=True.",
40783
- aiSpecific: true
42491
+ _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).",
42492
+ aiSpecific: true,
42493
+ _v7Verdict: "USEFUL",
42494
+ _v7Lift: 137559.75,
42495
+ _v7Recall: 0,
42496
+ _v7FpRate: 0,
42497
+ _v7Precision: 0.75,
42498
+ _v8Verdict: "INVERTED",
42499
+ _v8Lift: 0
40784
42500
  },
40785
- "ai/errors-near-eof": {
40786
- recall: 0.0697,
40787
- fpRate: 0.0548,
40788
- ratio: 1.27,
40789
- precision: 0.6225,
40790
- lastCalibratedAt: "2026-06-27T12:00:00Z",
40791
- verdict: "NOISY",
40792
- _calibrationNote: "v7 corpus re-calibration (2026-06-27, min-date=2025-01-01): 184488 neg + 239054 pos. NOISY \u2014 TP=16673, FP=10112, P=62.2%, FPR=5.48%, lift=1.3. aiSpecific=True.",
40793
- defaultOff: true,
40794
- aiSpecific: true
42501
+ "product/terminology-drift": {
42502
+ recall: 91e-4,
42503
+ fpRate: 21e-4,
42504
+ ratio: 397.75,
42505
+ precision: 0.8347,
42506
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
42507
+ verdict: "USEFUL",
42508
+ _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).",
42509
+ aiSpecific: false,
42510
+ _v7Verdict: "USEFUL",
42511
+ _v7Lift: 280.09,
42512
+ _v7Recall: 86e-4,
42513
+ _v7FpRate: 28e-4,
42514
+ _v7Precision: 0.7956,
42515
+ _v8Verdict: "USEFUL",
42516
+ _v8Lift: 8477.9
40795
42517
  },
40796
- "ai/any-density": {
40797
- recall: 55e-4,
40798
- fpRate: 41e-4,
40799
- ratio: 1.34,
40800
- precision: 0.634,
40801
- lastCalibratedAt: "2026-06-27T12:00:00Z",
40802
- verdict: "NOISY",
40803
- _calibrationNote: "v7 corpus re-calibration (2026-06-27, min-date=2025-01-01): 184488 neg + 239054 pos. NOISY \u2014 TP=1313, FP=758, P=63.4%, FPR=0.41%, lift=1.3. aiSpecific=True.",
40804
- defaultOff: true,
40805
- aiSpecific: true
42518
+ "product/ux-pattern-fragmentation": {
42519
+ recall: 1e-4,
42520
+ fpRate: 0,
42521
+ ratio: 22864.4,
42522
+ precision: 0.8163,
42523
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
42524
+ verdict: "USEFUL",
42525
+ _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).",
42526
+ aiSpecific: true,
42527
+ _v7Verdict: "USEFUL",
42528
+ _v7Lift: 18341.3,
42529
+ _v7Recall: 1e-4,
42530
+ _v7FpRate: 0,
42531
+ _v7Precision: 0.8,
42532
+ _v8Verdict: "USEFUL",
42533
+ _v8Lift: 61037.33
40806
42534
  },
40807
- "ai/renyi-profile": {
40808
- recall: 0,
42535
+ "rust/stringly-typed": {
42536
+ recall: 2e-4,
40809
42537
  fpRate: 0,
40810
- ratio: 0.26,
40811
- precision: 0.25,
40812
- lastCalibratedAt: "2026-06-27T12:00:00Z",
40813
- verdict: "INVERTED",
40814
- _calibrationNote: "v7 corpus re-calibration (2026-06-27, min-date=2025-01-01): 184488 neg + 239054 pos. INVERTED \u2014 TP=3, FP=9, P=25.0%, FPR=0.00%, lift=0.3. aiSpecific=True.",
40815
- defaultOff: true,
40816
- aiSpecific: true
42538
+ ratio: 24735.12,
42539
+ precision: 0.8831,
42540
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
42541
+ verdict: "USEFUL",
42542
+ _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).",
42543
+ aiSpecific: true,
42544
+ _v7Verdict: "DORMANT",
42545
+ _v7Lift: 1,
42546
+ _v7Recall: 0,
42547
+ _v7FpRate: 0,
42548
+ _v7Precision: 0,
42549
+ _v8Verdict: "USEFUL",
42550
+ _v8Lift: 6737.89
40817
42551
  },
40818
- "ai/log-rank-histogram": {
42552
+ "rust/todo-macro": {
42553
+ recall: 1e-4,
42554
+ fpRate: 7e-4,
42555
+ ratio: 210.08,
42556
+ precision: 0.1392,
42557
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
42558
+ verdict: "OK",
42559
+ _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).",
42560
+ aiSpecific: true,
42561
+ _v7Verdict: "DORMANT",
42562
+ _v7Lift: 1,
42563
+ _v7Recall: 0,
42564
+ _v7FpRate: 0,
42565
+ _v7Precision: 0,
42566
+ _v8Verdict: "OK",
42567
+ _v8Lift: 57.23
42568
+ },
42569
+ "rust/unused-pub-fn": {
40819
42570
  recall: 0,
40820
42571
  fpRate: 0,
40821
- ratio: 0,
40822
- precision: 0,
40823
- lastCalibratedAt: "2026-06-27T00:00:00Z",
42572
+ ratio: 10803.43,
42573
+ precision: 0.3,
42574
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
40824
42575
  verdict: "OK",
40825
- _calibrationNote: "v0.13.0 stub: rule implemented per Gehrmann 2019 GLTR; calibration on v7 corpus pending. v0.13.0: marked OK (peer-reviewed math backing; lift=0 because v7 calibration has not been run yet \u2014 will be re-evaluated).",
40826
- aiSpecific: true
42576
+ _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).",
42577
+ aiSpecific: true,
42578
+ _v7Verdict: "DORMANT",
42579
+ _v7Lift: 1,
42580
+ _v7Recall: 0,
42581
+ _v7FpRate: 0,
42582
+ _v7Precision: 0,
42583
+ _v8Verdict: "OK",
42584
+ _v8Lift: 2942.87
40827
42585
  },
40828
- "ai/segment-surprisal-cv": {
40829
- recall: 0.182,
40830
- fpRate: 0.0812,
40831
- ratio: 2.24,
40832
- precision: 0.7438,
40833
- lastCalibratedAt: "2026-06-27T12:00:00Z",
42586
+ "rust/unwrap-in-production": {
42587
+ recall: 8e-3,
42588
+ fpRate: 77e-4,
42589
+ ratio: 70.81,
42590
+ precision: 0.5475,
42591
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
40834
42592
  verdict: "USEFUL",
40835
- _calibrationNote: "v7 corpus re-calibration (2026-06-27, min-date=2025-01-01): 184488 neg + 239054 pos. USEFUL \u2014 TP=43498, FP=14983, P=74.4%, FPR=8.12%, lift=2.2. aiSpecific=True.",
40836
- aiSpecific: true
42593
+ _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).",
42594
+ aiSpecific: true,
42595
+ _v7Verdict: "DORMANT",
42596
+ _v7Lift: 1,
42597
+ _v7Recall: 0,
42598
+ _v7FpRate: 0,
42599
+ _v7Precision: 0,
42600
+ _v8Verdict: "USEFUL",
42601
+ _v8Lift: 19.29
40837
42602
  },
40838
- "ai/compression-profile": {
40839
- recall: 0.3139,
40840
- fpRate: 0.1489,
40841
- ratio: 2.11,
40842
- precision: 0.732,
40843
- lastCalibratedAt: "2026-06-27T12:00:00Z",
42603
+ "security/dangerous-cors": {
42604
+ recall: 5e-4,
42605
+ fpRate: 4e-4,
42606
+ ratio: 1721.87,
42607
+ precision: 0.6079,
42608
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
40844
42609
  verdict: "USEFUL",
40845
- _calibrationNote: "v7 corpus re-calibration (2026-06-27, min-date=2025-01-01): 184488 neg + 239054 pos. USEFUL \u2014 TP=75031, FP=27473, P=73.2%, FPR=14.89%, lift=2.1. aiSpecific=True.",
40846
- aiSpecific: true
42610
+ _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).",
42611
+ aiSpecific: true,
42612
+ _v7Verdict: "USEFUL",
42613
+ _v7Lift: 1257.16,
42614
+ _v7Recall: 5e-4,
42615
+ _v7FpRate: 5e-4,
42616
+ _v7Precision: 0.5758,
42617
+ _v8Verdict: "USEFUL",
42618
+ _v8Lift: 11365.57
40847
42619
  },
40848
- "ai/tailwind-color-overuse": {
40849
- recall: 0.0216,
40850
- fpRate: 52e-4,
40851
- ratio: 4.16,
40852
- precision: 0.8436,
40853
- lastCalibratedAt: "2026-06-27T12:00:00Z",
42620
+ "security/eval": {
42621
+ recall: 1e-4,
42622
+ fpRate: 2e-4,
42623
+ ratio: 1929.18,
42624
+ precision: 0.4286,
42625
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
42626
+ verdict: "OK",
42627
+ _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).",
42628
+ aiSpecific: false,
42629
+ _v7Verdict: "DORMANT",
42630
+ _v7Lift: 1,
42631
+ _v7Recall: 0,
42632
+ _v7FpRate: 0,
42633
+ _v7Precision: 0,
42634
+ _v8Verdict: "OK",
42635
+ _v8Lift: 525.51
42636
+ },
42637
+ "security/exposed-env-var": {
42638
+ recall: 6e-4,
42639
+ fpRate: 5e-4,
42640
+ ratio: 1055.81,
42641
+ precision: 0.5696,
42642
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
40854
42643
  verdict: "USEFUL",
40855
- _calibrationNote: "v7 corpus re-calibration (2026-06-27, min-date=2025-01-01): 184488 neg + 239054 pos. USEFUL \u2014 TP=5169, FP=958, P=84.4%, FPR=0.52%, lift=4.2. aiSpecific=True.",
40856
- aiSpecific: true
42644
+ _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).",
42645
+ aiSpecific: false,
42646
+ _v7Verdict: "USEFUL",
42647
+ _v7Lift: 790.5,
42648
+ _v7Recall: 6e-4,
42649
+ _v7FpRate: 7e-4,
42650
+ _v7Precision: 0.5387,
42651
+ _v8Verdict: "USEFUL",
42652
+ _v8Lift: 4716.52
40857
42653
  },
40858
- "ai/default-react-stack": {
40859
- recall: 1e-3,
42654
+ "security/fail-open-auth": {
42655
+ recall: 0,
40860
42656
  fpRate: 0,
40861
- ratio: 99.99,
40862
- precision: 0.9957,
40863
- lastCalibratedAt: "2026-06-27T12:00:00Z",
42657
+ ratio: 99999,
42658
+ precision: 1,
42659
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
40864
42660
  verdict: "USEFUL",
40865
- _calibrationNote: "v7 corpus re-calibration (2026-06-27, min-date=2025-01-01): 184488 neg + 239054 pos. USEFUL \u2014 TP=231, FP=1, P=99.6%, FPR=0.00%, lift=178.3. aiSpecific=True.",
40866
- aiSpecific: true
42661
+ _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).",
42662
+ aiSpecific: true,
42663
+ _v7Verdict: "USEFUL",
42664
+ _v7Lift: 99999,
42665
+ _v7Recall: 0,
42666
+ _v7FpRate: 0,
42667
+ _v7Precision: 1,
42668
+ _v8Verdict: "DORMANT",
42669
+ _v8Lift: 1
40867
42670
  },
40868
- "ai/library-reinvention": {
40869
- recall: 3e-4,
42671
+ "security/hardcoded-secret": {
42672
+ recall: 14e-4,
42673
+ fpRate: 6e-4,
42674
+ ratio: 1269.08,
42675
+ precision: 0.735,
42676
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
42677
+ verdict: "USEFUL",
42678
+ _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).",
42679
+ aiSpecific: true,
42680
+ _v7Verdict: "USEFUL",
42681
+ _v7Lift: 916.92,
42682
+ _v7Recall: 13e-4,
42683
+ _v7FpRate: 8e-4,
42684
+ _v7Precision: 0.6899,
42685
+ _v8Verdict: "USEFUL",
42686
+ _v8Lift: 7935.57
42687
+ },
42688
+ "security/localstorage-token": {
42689
+ recall: 1e-4,
40870
42690
  fpRate: 0,
40871
- ratio: 9.88,
40872
- precision: 0.9275,
40873
- lastCalibratedAt: "2026-06-27T12:00:00Z",
42691
+ ratio: 99999,
42692
+ precision: 1,
42693
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
40874
42694
  verdict: "USEFUL",
40875
- _calibrationNote: "v7 corpus re-calibration (2026-06-27, min-date=2025-01-01): 184488 neg + 239054 pos. USEFUL \u2014 TP=64, FP=5, P=92.8%, FPR=0.00%, lift=9.9. aiSpecific=True.",
40876
- aiSpecific: true
42695
+ _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).",
42696
+ aiSpecific: false,
42697
+ _v7Verdict: "DORMANT",
42698
+ _v7Lift: 1,
42699
+ _v7Recall: 0,
42700
+ _v7FpRate: 0,
42701
+ _v7Precision: 0,
42702
+ _v8Verdict: "USEFUL",
42703
+ _v8Lift: 99999
40877
42704
  },
40878
- "ai/state-default-overuse": {
40879
- recall: 29e-4,
40880
- fpRate: 9e-4,
40881
- ratio: 3.42,
40882
- precision: 0.8161,
40883
- lastCalibratedAt: "2026-06-27T12:00:00Z",
42705
+ "security/missing-auth-check": {
42706
+ recall: 5e-4,
42707
+ fpRate: 0,
42708
+ ratio: 99999,
42709
+ precision: 1,
42710
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
40884
42711
  verdict: "USEFUL",
40885
- _calibrationNote: "v7 corpus re-calibration (2026-06-27, min-date=2025-01-01): 184488 neg + 239054 pos. USEFUL \u2014 TP=701, FP=158, P=81.6%, FPR=0.09%, lift=3.4. aiSpecific=True.",
40886
- aiSpecific: true
42712
+ _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).",
42713
+ aiSpecific: false,
42714
+ _v7Verdict: "DORMANT",
42715
+ _v7Lift: 1,
42716
+ _v7Recall: 0,
42717
+ _v7FpRate: 0,
42718
+ _v7Precision: 0,
42719
+ _v8Verdict: "USEFUL",
42720
+ _v8Lift: 99999
40887
42721
  },
40888
- "ai/fetch-default-overuse": {
40889
- recall: 28e-4,
40890
- fpRate: 4e-4,
40891
- ratio: 6.76,
40892
- precision: 0.8976,
40893
- lastCalibratedAt: "2026-06-27T12:00:00Z",
42722
+ "security/public-admin-route": {
42723
+ recall: 38e-4,
42724
+ fpRate: 38e-4,
42725
+ ratio: 142.2,
42726
+ precision: 0.5376,
42727
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
40894
42728
  verdict: "USEFUL",
40895
- _calibrationNote: "v7 corpus re-calibration (2026-06-27, min-date=2025-01-01): 184488 neg + 239054 pos. USEFUL \u2014 TP=666, FP=76, P=89.8%, FPR=0.04%, lift=6.8. aiSpecific=True.",
40896
- aiSpecific: true
42729
+ _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).",
42730
+ aiSpecific: false,
42731
+ _v7Verdict: "DORMANT",
42732
+ _v7Lift: 1,
42733
+ _v7Recall: 0,
42734
+ _v7FpRate: 0,
42735
+ _v7Precision: 0,
42736
+ _v8Verdict: "USEFUL",
42737
+ _v8Lift: 38.74
40897
42738
  },
40898
- "ai/console-debug-storm": {
40899
- recall: 8e-3,
40900
- fpRate: 9e-4,
40901
- ratio: 8.43,
40902
- precision: 0.9161,
40903
- lastCalibratedAt: "2026-06-27T12:00:00Z",
42739
+ "security/sql-construction": {
42740
+ recall: 32e-4,
42741
+ fpRate: 15e-4,
42742
+ ratio: 485.42,
42743
+ precision: 0.7183,
42744
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
40904
42745
  verdict: "USEFUL",
40905
- _calibrationNote: "v7 corpus re-calibration (2026-06-27, min-date=2025-01-01): 184488 neg + 239054 pos. USEFUL \u2014 TP=1912, FP=175, P=91.6%, FPR=0.09%, lift=8.4. aiSpecific=True.",
40906
- aiSpecific: true
42746
+ _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).",
42747
+ aiSpecific: true,
42748
+ _v7Verdict: "USEFUL",
42749
+ _v7Lift: 370.52,
42750
+ _v7Recall: 3e-3,
42751
+ _v7FpRate: 18e-4,
42752
+ _v7Precision: 0.6788,
42753
+ _v8Verdict: "USEFUL",
42754
+ _v8Lift: 1608.86
40907
42755
  },
40908
- "db/missing-fk-index": {
40909
- recall: 0,
42756
+ "security/target-blank-no-noopener": {
42757
+ recall: 4e-4,
40910
42758
  fpRate: 0,
40911
- ratio: 0,
40912
- precision: 0,
40913
- lastCalibratedAt: "2026-06-30T00:00:00Z",
40914
- verdict: "DORMANT",
40915
- defaultOff: true,
40916
- _calibrationNote: "v0.17.0 ship \u2014 not in v7 per-rule table. Default-off until calibration data lands. Backed by: PostgreSQL Global Development Group (2024), *PostgreSQL 16 Documentation \xA75.4 (Constraints)*, https://www.postgresql.org/docs/16/ddl-constraints.html; Squawk (2023), *Postgres linter rules*, https://github.com/sqllabs/squawk, rule `require-index-for-fk`. (Foreign key columns need a matching index \u2014 sequential scan on parent delete is a canonical Postgres anti-pattern.)",
40917
- aiSpecific: false
42759
+ ratio: 26141.63,
42760
+ precision: 0.9333,
42761
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
42762
+ verdict: "USEFUL",
42763
+ _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).",
42764
+ aiSpecific: false,
42765
+ _v7Verdict: "DORMANT",
42766
+ _v7Lift: 1,
42767
+ _v7Recall: 0,
42768
+ _v7FpRate: 0,
42769
+ _v7Precision: 0,
42770
+ _v8Verdict: "USEFUL",
42771
+ _v8Lift: 7121.02
40918
42772
  },
40919
- "db/duplicate-index": {
40920
- recall: 0,
40921
- fpRate: 0,
40922
- ratio: 0,
40923
- precision: 0,
40924
- lastCalibratedAt: "2026-06-30T00:00:00Z",
40925
- verdict: "DORMANT",
40926
- defaultOff: true,
40927
- _calibrationNote: "v0.17.0 ship \u2014 not in v7 per-rule table. Default-off until calibration data lands. Backed by: PostgreSQL Global Development Group (2024), *PostgreSQL 16 Documentation \xA711.2 (Index Types)*; Heroku Postgres Team (2018), *Efficient Use of PostgreSQL Indexes*. (Duplicate indexes silently double write cost without read benefit \u2014 Postgres does not warn.)",
40928
- aiSpecific: false
42773
+ "security/unsafe-html-render": {
42774
+ recall: 13e-4,
42775
+ fpRate: 11e-4,
42776
+ ratio: 513.12,
42777
+ precision: 0.574,
42778
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
42779
+ verdict: "USEFUL",
42780
+ _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).",
42781
+ aiSpecific: false,
42782
+ _v7Verdict: "USEFUL",
42783
+ _v7Lift: 757.74,
42784
+ _v7Recall: 13e-4,
42785
+ _v7FpRate: 9e-4,
42786
+ _v7Precision: 0.661,
42787
+ _v8Verdict: "OK",
42788
+ _v8Lift: 201.44
40929
42789
  },
40930
- "db/missing-not-null": {
40931
- recall: 0,
42790
+ "test/duplicate-setup": {
42791
+ recall: 1e-4,
40932
42792
  fpRate: 0,
40933
- ratio: 0,
40934
- precision: 0,
40935
- lastCalibratedAt: "2026-06-30T00:00:00Z",
40936
- verdict: "DORMANT",
40937
- defaultOff: true,
40938
- _calibrationNote: "v0.17.0 ship \u2014 not in v7 per-rule table. Default-off until calibration data lands. Backed by: PostgreSQL Global Development Group (2024), *PostgreSQL 16 Documentation \xA75.4.1 (Check Constraints)*; Kleppmann, M. (2017), *Designing Data-Intensive Applications*, O'Reilly, ch.4 (NULL semantics in RDBMS). (Required-identifier columns without NOT NULL produce silent NULL inserts \u2014 canonical AI SQL smell.)",
40939
- aiSpecific: false
42793
+ ratio: 51016.19,
42794
+ precision: 0.8095,
42795
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
42796
+ verdict: "USEFUL",
42797
+ _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).",
42798
+ aiSpecific: true,
42799
+ _v7Verdict: "USEFUL",
42800
+ _v7Lift: 50348.67,
42801
+ _v7Recall: 1e-4,
42802
+ _v7FpRate: 0,
42803
+ _v7Precision: 0.8235,
42804
+ _v8Verdict: "USEFUL",
42805
+ _v8Lift: 51500.25
40940
42806
  },
40941
- "db/enum-sprawl": {
40942
- recall: 0,
40943
- fpRate: 0,
40944
- ratio: 0,
40945
- precision: 0,
40946
- lastCalibratedAt: "2026-06-30T00:00:00Z",
40947
- verdict: "DORMANT",
40948
- defaultOff: true,
40949
- _calibrationNote: "v0.17.0 ship \u2014 not in v7 per-rule table. Default-off until calibration data lands. Backed by: PostgreSQL Global Development Group (2024), *PostgreSQL 16 Documentation \xA78.7 (Enumerated Types)*; Borkowski, A. (2022), *PostgreSQL enum types: when to use them and when not to*, pgconfig.org. (Enums with >12 values are brittle to extend and hard to localize \u2014 lookup table is the standard replacement.)",
40950
- aiSpecific: false
42807
+ "test/fake-placeholder": {
42808
+ recall: 51e-4,
42809
+ fpRate: 15e-4,
42810
+ ratio: 547.47,
42811
+ precision: 0.8014,
42812
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
42813
+ verdict: "USEFUL",
42814
+ _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).",
42815
+ aiSpecific: true,
42816
+ _v7Verdict: "USEFUL",
42817
+ _v7Lift: 418.76,
42818
+ _v7Recall: 53e-4,
42819
+ _v7FpRate: 19e-4,
42820
+ _v7Precision: 0.7854,
42821
+ _v8Verdict: "USEFUL",
42822
+ _v8Lift: 2477.4
40951
42823
  },
40952
- "db/naming-inconsistency": {
42824
+ "test/missing-edge-case": {
40953
42825
  recall: 0,
40954
42826
  fpRate: 0,
40955
42827
  ratio: 0,
40956
42828
  precision: 0,
40957
- lastCalibratedAt: "2026-06-30T00:00:00Z",
42829
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
40958
42830
  verdict: "DORMANT",
40959
- defaultOff: true,
40960
- _calibrationNote: "v0.17.0 ship \u2014 not in v7 per-rule table. Default-off until calibration data lands. Backed by: PostgreSQL Global Development Group (2024), *PostgreSQL 16 Documentation \xA74.1.1 (Identifiers and Key Words)*; pgsql-hackers (2018), *Re: snake_case vs camelCase in Postgres identifiers*. (snake_case is the Postgres convention; mixing styles in the same schema breaks ORM generators.)",
40961
- aiSpecific: false
42831
+ _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.",
42832
+ aiSpecific: true,
42833
+ _v7Verdict: "DORMANT",
42834
+ _v7Lift: 0,
42835
+ _v7Recall: 0,
42836
+ _v7FpRate: 0,
42837
+ _v7Precision: 0,
42838
+ _v8Verdict: "DORMANT",
42839
+ _v8Lift: 1,
42840
+ defaultOff: true
40962
42841
  },
40963
- "db/sql-concat": {
40964
- recall: 0,
40965
- fpRate: 0,
40966
- ratio: 0,
40967
- precision: 0,
40968
- lastCalibratedAt: "2026-06-30T00:00:00Z",
40969
- verdict: "DORMANT",
40970
- defaultOff: true,
40971
- _calibrationNote: "v0.17.0 ship \u2014 not in v7 per-rule table. Default-off until calibration data lands. Backed by: OWASP Foundation (2021), *OWASP Top 10 \u2014 A03:2021 Injection*, https://owasp.org/Top10/A03_2021-Injection/; OWASP Foundation (2017), *SQL Injection Prevention Cheat Sheet*. (Template-literal SQL with ${...} interpolation is the #1 SQL injection vector in AI-generated TypeScript code.)",
40972
- aiSpecific: true
42842
+ "test/weak-assertion": {
42843
+ recall: 0.0417,
42844
+ fpRate: 67e-4,
42845
+ ratio: 131.62,
42846
+ precision: 0.8793,
42847
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
42848
+ verdict: "USEFUL",
42849
+ _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).",
42850
+ aiSpecific: true,
42851
+ _v7Verdict: "USEFUL",
42852
+ _v7Lift: 99.9,
42853
+ _v7Recall: 0.0418,
42854
+ _v7FpRate: 86e-4,
42855
+ _v7Precision: 0.8622,
42856
+ _v8Verdict: "USEFUL",
42857
+ _v8Lift: 651.94
40973
42858
  },
40974
- "dead/unused-import": {
42859
+ "typo/calc-fontsize": {
40975
42860
  recall: 0,
40976
42861
  fpRate: 0,
40977
42862
  ratio: 0,
40978
42863
  precision: 0,
40979
- lastCalibratedAt: "2026-06-30T00:00:00Z",
42864
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
40980
42865
  verdict: "DORMANT",
40981
- defaultOff: true,
40982
- _calibrationNote: "v0.18.5 ship \u2014 not in v7 per-rule table. Default-off until v8 calibration data lands. The first of 5 planned `dead/*` rules (this one + dead/unused-local + dead/unused-parameter + dead/dead-branch + dead/unreachable). The pattern is the canonical AI-iteration rot: the model adds an import when introducing a feature, then rewrites the function later without cleaning up. Most real-world tsconfig.json files have `noUnusedLocals: false`, so tsc never fires.",
40983
- aiSpecific: true
42866
+ _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.",
42867
+ aiSpecific: false,
42868
+ _v7Verdict: "DORMANT",
42869
+ _v7Lift: 0,
42870
+ _v7Recall: 0,
42871
+ _v7FpRate: 0,
42872
+ _v7Precision: 0,
42873
+ _v8Verdict: "DORMANT",
42874
+ _v8Lift: 1,
42875
+ defaultOff: true
40984
42876
  },
40985
- "dead/unused-local": {
42877
+ "typo/calc-raw-px": {
40986
42878
  recall: 0,
40987
42879
  fpRate: 0,
40988
- ratio: 0,
40989
- precision: 0,
40990
- lastCalibratedAt: "2026-06-30T00:00:00Z",
40991
- verdict: "DORMANT",
40992
- defaultOff: true,
40993
- _calibrationNote: "v0.18.5b ship \u2014 not in v7 per-rule table. Default-off until v8 calibration data lands. The second of 5 planned `dead/*` rules. Muchnick 1997 Ch. 13 'liveness analysis' (textbook compiler optimization).",
40994
- aiSpecific: true
42880
+ ratio: 210066.67,
42881
+ precision: 0.8333,
42882
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
42883
+ verdict: "USEFUL",
42884
+ _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).",
42885
+ aiSpecific: false,
42886
+ _v7Verdict: "USEFUL",
42887
+ _v7Lift: 137559.75,
42888
+ _v7Recall: 0,
42889
+ _v7FpRate: 0,
42890
+ _v7Precision: 0.75,
42891
+ _v8Verdict: "USEFUL",
42892
+ _v8Lift: 99999
40995
42893
  },
40996
- "dead/unused-parameter": {
42894
+ "typo/clamp-offscale": {
40997
42895
  recall: 0,
40998
42896
  fpRate: 0,
40999
42897
  ratio: 0,
41000
42898
  precision: 0,
41001
- lastCalibratedAt: "2026-06-30T00:00:00Z",
42899
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
41002
42900
  verdict: "DORMANT",
41003
- defaultOff: true,
41004
- _calibrationNote: "v0.18.5b ship \u2014 not in v7 per-rule table. Default-off until v8 calibration data lands. The third of 5 planned `dead/*` rules. AI agents add parameters when introducing features, then rewrite the function without removing parameters the new code does not need.",
41005
- aiSpecific: true
42901
+ _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.",
42902
+ aiSpecific: false,
42903
+ _v7Verdict: "DORMANT",
42904
+ _v7Lift: 0,
42905
+ _v7Recall: 0,
42906
+ _v7FpRate: 0,
42907
+ _v7Precision: 0,
42908
+ _v8Verdict: "DORMANT",
42909
+ _v8Lift: 1,
42910
+ defaultOff: true
41006
42911
  },
41007
- "dead/dead-branch": {
41008
- recall: 0,
41009
- fpRate: 0,
41010
- ratio: 0,
41011
- precision: 0,
41012
- lastCalibratedAt: "2026-06-30T00:00:00Z",
41013
- verdict: "DORMANT",
41014
- defaultOff: true,
41015
- _calibrationNote: "v0.18.5b ship \u2014 not in v7 per-rule table. Default-off until v8 calibration data lands. The fourth of 5 planned `dead/*` rules. AI-iteration signature: feature flag toggled to a constant, or wrapper from a previous refactor.",
41016
- aiSpecific: true
42912
+ "typo/math-button-label-uniformity": {
42913
+ recall: 1e-4,
42914
+ fpRate: 1e-4,
42915
+ ratio: 6894.19,
42916
+ precision: 0.629,
42917
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
42918
+ verdict: "USEFUL",
42919
+ _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).",
42920
+ aiSpecific: false,
42921
+ _v7Verdict: "USEFUL",
42922
+ _v7Lift: 5571.66,
42923
+ _v7Recall: 2e-4,
42924
+ _v7FpRate: 1e-4,
42925
+ _v7Precision: 0.6379,
42926
+ _v8Verdict: "USEFUL",
42927
+ _v8Lift: 17166.75
41017
42928
  },
41018
- "dead/unreachable": {
42929
+ "typo/math-cta-vocabulary": {
41019
42930
  recall: 0,
41020
42931
  fpRate: 0,
41021
42932
  ratio: 0,
41022
42933
  precision: 0,
41023
- lastCalibratedAt: "2026-06-30T00:00:00Z",
42934
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
41024
42935
  verdict: "DORMANT",
41025
- defaultOff: true,
41026
- _calibrationNote: "v0.18.5b ship \u2014 not in v7 per-rule table. Default-off until v8 calibration data lands. The fifth of 5 planned `dead/*` rules. AI-iteration signature: model added an early return for a new error path, then forgot the rest of the function body was still sitting below it.",
41027
- aiSpecific: true
42936
+ _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.",
42937
+ aiSpecific: true,
42938
+ _v7Verdict: "DORMANT",
42939
+ _v7Lift: 0,
42940
+ _v7Recall: 0,
42941
+ _v7FpRate: 0,
42942
+ _v7Precision: 0,
42943
+ _v8Verdict: "DORMANT",
42944
+ _v8Lift: 1,
42945
+ defaultOff: true
41028
42946
  },
41029
- "docs/stale-package-reference": {
41030
- recall: 0,
42947
+ "typo/placeholder-text": {
42948
+ recall: 1e-4,
41031
42949
  fpRate: 0,
41032
- ratio: 0,
41033
- precision: 0,
41034
- lastCalibratedAt: "2026-06-30T00:00:00Z",
41035
- verdict: "DORMANT",
41036
- defaultOff: true,
41037
- _calibrationNote: "v0.17.0 ship \u2014 not in v7 per-rule table. Default-off until calibration data lands. Backed by: Meng, M. et al. (2020), *The Cost of Fixing Code Documentation: An Empirical Study on Open-Source Software*, ICSE 2020; Aghajani, E. et al. (2019), *Software documentation: a practitioners' perspective*, ICSE 2019. (Doc references to undeclared packages are copy-paste rot from previous projects \u2014 high-signal doc drift.)",
41038
- aiSpecific: false
42950
+ ratio: 17330.5,
42951
+ precision: 0.6875,
42952
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
42953
+ verdict: "USEFUL",
42954
+ _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).",
42955
+ aiSpecific: false,
42956
+ _v7Verdict: "DORMANT",
42957
+ _v7Lift: 1,
42958
+ _v7Recall: 0,
42959
+ _v7FpRate: 0,
42960
+ _v7Precision: 0,
42961
+ _v8Verdict: "USEFUL",
42962
+ _v8Lift: 4720.86
41039
42963
  },
41040
- "docs/stale-function-reference": {
42964
+ "visual/arbitrary-escape": {
42965
+ recall: 26e-4,
42966
+ fpRate: 7e-4,
42967
+ ratio: 1219.67,
42968
+ precision: 0.8177,
42969
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
42970
+ verdict: "USEFUL",
42971
+ _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).",
42972
+ aiSpecific: true,
42973
+ _v7Verdict: "USEFUL",
42974
+ _v7Lift: 846.78,
42975
+ _v7Recall: 25e-4,
42976
+ _v7FpRate: 9e-4,
42977
+ _v7Precision: 0.7802,
42978
+ _v8Verdict: "USEFUL",
42979
+ _v8Lift: 99999
42980
+ },
42981
+ "visual/clamp-soup": {
41041
42982
  recall: 0,
41042
42983
  fpRate: 0,
41043
42984
  ratio: 0,
41044
42985
  precision: 0,
41045
- lastCalibratedAt: "2026-06-30T00:00:00Z",
42986
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
41046
42987
  verdict: "DORMANT",
41047
- defaultOff: true,
41048
- _calibrationNote: "v0.17.0 ship \u2014 not in v7 per-rule table. Default-off until calibration data lands. Backed by: Meng, M. et al. (2020), *The Cost of Fixing Code Documentation*; Chen, Z. et al. (2022), *An Empirical Study on Code Documentation Adequacy*, MSR 2022. (Doc callouts to non-existent exports \u2014 readers copy-paste and hit a runtime error.)",
41049
- aiSpecific: false
42988
+ _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.",
42989
+ aiSpecific: true,
42990
+ _v7Verdict: "DORMANT",
42991
+ _v7Lift: 0,
42992
+ _v7Recall: 0,
42993
+ _v7FpRate: 0,
42994
+ _v7Precision: 0,
42995
+ _v8Verdict: "DORMANT",
42996
+ _v8Lift: 1,
42997
+ defaultOff: true
41050
42998
  },
41051
- "docs/expired-code-example": {
42999
+ "visual/generic-centering": {
41052
43000
  recall: 0,
41053
43001
  fpRate: 0,
41054
43002
  ratio: 0,
41055
43003
  precision: 0,
41056
- lastCalibratedAt: "2026-06-30T00:00:00Z",
43004
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
41057
43005
  verdict: "DORMANT",
41058
- defaultOff: true,
41059
- _calibrationNote: "v0.17.0 ship \u2014 not in v7 per-rule table. Default-off until calibration data lands. Backed by: Parnas, D.L. (2010), *Precise Documentation: The Key to Better Software*, Springer (canonical doc-correctness argument); Chen, Z. et al. (2022). (Fenced code examples with broken imports erode trust in the entire docs site.)",
41060
- aiSpecific: false
43006
+ _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.",
43007
+ aiSpecific: true,
43008
+ _v7Verdict: "DORMANT",
43009
+ _v7Lift: 0,
43010
+ _v7Recall: 0,
43011
+ _v7FpRate: 0,
43012
+ _v7Precision: 0,
43013
+ _v8Verdict: "DORMANT",
43014
+ _v8Lift: 1,
43015
+ defaultOff: true
41061
43016
  },
41062
- "docs/broken-link": {
41063
- recall: 0,
43017
+ "visual/inline-style-dominance": {
43018
+ recall: 0.0103,
43019
+ fpRate: 52e-4,
43020
+ ratio: 134.59,
43021
+ precision: 0.6983,
43022
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
43023
+ verdict: "USEFUL",
43024
+ _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).",
43025
+ aiSpecific: false,
43026
+ _v7Verdict: "USEFUL",
43027
+ _v7Lift: 98.17,
43028
+ _v7Recall: 97e-4,
43029
+ _v7FpRate: 67e-4,
43030
+ _v7Precision: 0.6535,
43031
+ _v8Verdict: "USEFUL",
43032
+ _v8Lift: 704.71
43033
+ },
43034
+ "visual/math-color-cluster": {
43035
+ recall: 2e-4,
41064
43036
  fpRate: 0,
41065
- ratio: 0,
41066
- precision: 0,
41067
- lastCalibratedAt: "2026-06-30T00:00:00Z",
41068
- verdict: "DORMANT",
41069
- defaultOff: true,
41070
- _calibrationNote: "v0.17.0 ship \u2014 not in v7 per-rule table. Default-off until calibration data lands. Backed by: Nielsen, J. (2000), *Designing Web Usability*, New Riders (broken links as a top-5 trust erosion signal); Google Search Central (2024), *Crawl errors documentation*, https://developers.google.com/search/docs/crawling-indexing. (Broken internal links cost SEO crawl budget and reader trust.)",
41071
- aiSpecific: false
43037
+ ratio: 46814.86,
43038
+ precision: 0.9286,
43039
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
43040
+ verdict: "USEFUL",
43041
+ _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).",
43042
+ aiSpecific: true,
43043
+ _v7Verdict: "USEFUL",
43044
+ _v7Lift: 33771.28,
43045
+ _v7Recall: 2e-4,
43046
+ _v7FpRate: 0,
43047
+ _v7Precision: 0.9206,
43048
+ _v8Verdict: "USEFUL",
43049
+ _v8Lift: 99999
41072
43050
  },
41073
- "security/eval": {
43051
+ "visual/math-default-font": {
43052
+ recall: 16e-4,
43053
+ fpRate: 3e-4,
43054
+ ratio: 3035.16,
43055
+ precision: 0.8669,
43056
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
43057
+ verdict: "USEFUL",
43058
+ _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).",
43059
+ aiSpecific: true,
43060
+ _v7Verdict: "USEFUL",
43061
+ _v7Lift: 2105.64,
43062
+ _v7Recall: 13e-4,
43063
+ _v7FpRate: 4e-4,
43064
+ _v7Precision: 0.8151,
43065
+ _v8Verdict: "USEFUL",
43066
+ _v8Lift: 68229.63
43067
+ },
43068
+ "visual/math-font-entropy": {
43069
+ recall: 52e-4,
43070
+ fpRate: 1e-3,
43071
+ ratio: 869.95,
43072
+ precision: 0.8593,
43073
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
43074
+ verdict: "USEFUL",
43075
+ _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).",
43076
+ aiSpecific: true,
43077
+ _v7Verdict: "USEFUL",
43078
+ _v7Lift: 600.09,
43079
+ _v7Recall: 45e-4,
43080
+ _v7FpRate: 14e-4,
43081
+ _v7Precision: 0.8114,
43082
+ _v8Verdict: "USEFUL",
43083
+ _v8Lift: 68516.08
43084
+ },
43085
+ "visual/math-gradient-hue-rotation": {
41074
43086
  recall: 0,
41075
43087
  fpRate: 0,
41076
43088
  ratio: 0,
41077
43089
  precision: 0,
41078
- lastCalibratedAt: "2026-06-30T00:00:00Z",
43090
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
41079
43091
  verdict: "DORMANT",
41080
- defaultOff: true,
41081
- _calibrationNote: "v0.16.0 ship \u2014 not in v7 per-rule table. Default-off until calibration data lands. Backed by: OWASP Foundation (2021), *OWASP Top 10 \u2014 A03:2021 Injection*; Mozilla Developer Network (2024), *eval() \u2014 MDN Web Docs*, https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval (Security Considerations). (eval() and new Function() are RCE vectors if the input is ever attacker-controlled.)",
41082
- aiSpecific: false
43092
+ _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.",
43093
+ aiSpecific: true,
43094
+ _v7Verdict: "DORMANT",
43095
+ _v7Lift: 0,
43096
+ _v7Recall: 0,
43097
+ _v7FpRate: 0,
43098
+ _v7Precision: 0,
43099
+ _v8Verdict: "DORMANT",
43100
+ _v8Lift: 1,
43101
+ defaultOff: true
41083
43102
  },
41084
- "security/localstorage-token": {
41085
- recall: 0,
43103
+ "visual/math-rounded-entropy": {
43104
+ recall: 38e-4,
43105
+ fpRate: 2e-4,
43106
+ ratio: 3785.45,
43107
+ precision: 0.9461,
43108
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
43109
+ verdict: "USEFUL",
43110
+ _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).",
43111
+ aiSpecific: true,
43112
+ _v7Verdict: "USEFUL",
43113
+ _v7Lift: 2762.74,
43114
+ _v7Recall: 37e-4,
43115
+ _v7FpRate: 3e-4,
43116
+ _v7Precision: 0.9339,
43117
+ _v8Verdict: "USEFUL",
43118
+ _v8Lift: 68368.45
43119
+ },
43120
+ "visual/math-spacing-entropy": {
43121
+ recall: 18e-4,
43122
+ fpRate: 4e-4,
43123
+ ratio: 1898.99,
43124
+ precision: 0.8287,
43125
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
43126
+ verdict: "USEFUL",
43127
+ _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).",
43128
+ aiSpecific: true,
43129
+ _v7Verdict: "USEFUL",
43130
+ _v7Lift: 1339.22,
43131
+ _v7Recall: 18e-4,
43132
+ _v7FpRate: 6e-4,
43133
+ _v7Precision: 0.7959,
43134
+ _v8Verdict: "USEFUL",
43135
+ _v8Lift: 68031.19
43136
+ },
43137
+ "visual/naturalness-anomaly": {
43138
+ recall: 0.1729,
43139
+ fpRate: 0.0687,
43140
+ ratio: 10.86,
43141
+ precision: 0.746,
43142
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
43143
+ verdict: "USEFUL",
43144
+ _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).",
43145
+ aiSpecific: true,
43146
+ _v7Verdict: "USEFUL",
43147
+ _v7Lift: 12.5,
43148
+ _v7Recall: 0.1659,
43149
+ _v7FpRate: 0.0621,
43150
+ _v7Precision: 0.7755,
43151
+ _v8Verdict: "USEFUL",
43152
+ _v8Lift: 7.64
43153
+ },
43154
+ "visual/radius-scale-violation": {
43155
+ recall: 4e-4,
41086
43156
  fpRate: 0,
41087
- ratio: 0,
41088
- precision: 0,
41089
- lastCalibratedAt: "2026-06-30T00:00:00Z",
41090
- verdict: "DORMANT",
41091
- defaultOff: true,
41092
- _calibrationNote: "v0.16.0 ship \u2014 not in v7 per-rule table. Default-off until calibration data lands. Backed by: OWASP Foundation (2021), *OWASP Top 10 \u2014 A07:2021 Identification and Authentication Failures*; OWASP Foundation (2022), *HTML5 Security Cheat Sheet \xA72.1 (Local Storage)*. (JWT/access/refresh tokens in localStorage are readable by any XSS payload \u2014 issue as httpOnly cookies instead.)",
41093
- aiSpecific: false
43157
+ ratio: 82131.33,
43158
+ precision: 0.9774,
43159
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
43160
+ verdict: "USEFUL",
43161
+ _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).",
43162
+ aiSpecific: false,
43163
+ _v7Verdict: "USEFUL",
43164
+ _v7Lift: 59285.01,
43165
+ _v7Recall: 4e-4,
43166
+ _v7FpRate: 0,
43167
+ _v7Precision: 0.9697,
43168
+ _v8Verdict: "USEFUL",
43169
+ _v8Lift: 99999
41094
43170
  },
41095
- "security/target-blank-no-noopener": {
43171
+ "visual/spacing-scale-violation": {
43172
+ recall: 86e-4,
43173
+ fpRate: 28e-4,
43174
+ ratio: 273.97,
43175
+ precision: 0.7792,
43176
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
43177
+ verdict: "USEFUL",
43178
+ _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).",
43179
+ aiSpecific: false,
43180
+ _v7Verdict: "USEFUL",
43181
+ _v7Lift: 187.83,
43182
+ _v7Recall: 84e-4,
43183
+ _v7FpRate: 39e-4,
43184
+ _v7Precision: 0.7342,
43185
+ _v8Verdict: "USEFUL",
43186
+ _v8Lift: 99999
43187
+ },
43188
+ "wcag/dragging-movements": {
41096
43189
  recall: 0,
41097
43190
  fpRate: 0,
41098
- ratio: 0,
41099
- precision: 0,
41100
- lastCalibratedAt: "2026-06-30T00:00:00Z",
41101
- verdict: "DORMANT",
41102
- defaultOff: true,
41103
- _calibrationNote: 'v0.16.0 ship \u2014 not in v7 per-rule table. Default-off until calibration data lands. Backed by: OWASP Foundation (2022), *HTML5 Security Cheat Sheet \xA72.3 (Tabnabbing)*; WHATWG (2024), *HTML Living Standard \u2014 Link types: noopener*. (target="_blank" without rel="noopener" lets the linked page control window.opener \u2014 reverse tabnabbing.)',
41104
- aiSpecific: false
43191
+ ratio: 33610.67,
43192
+ precision: 0.4,
43193
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
43194
+ verdict: "OK",
43195
+ _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).",
43196
+ aiSpecific: false,
43197
+ _v7Verdict: "OK",
43198
+ _v7Lift: 24455.07,
43199
+ _v7Recall: 0,
43200
+ _v7FpRate: 0,
43201
+ _v7Precision: 0.4,
43202
+ _v8Verdict: "DORMANT",
43203
+ _v8Lift: 1
43204
+ },
43205
+ "wcag/focus-appearance": {
43206
+ recall: 28e-4,
43207
+ fpRate: 1e-4,
43208
+ ratio: 8397.24,
43209
+ precision: 0.966,
43210
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
43211
+ verdict: "USEFUL",
43212
+ _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).",
43213
+ aiSpecific: false,
43214
+ _v7Verdict: "USEFUL",
43215
+ _v7Lift: 7353.82,
43216
+ _v7Recall: 26e-4,
43217
+ _v7FpRate: 1e-4,
43218
+ _v7Precision: 0.9623,
43219
+ _v8Verdict: "USEFUL",
43220
+ _v8Lift: 13418.41
43221
+ },
43222
+ "wcag/focus-obscured": {
43223
+ recall: 33e-4,
43224
+ fpRate: 7e-4,
43225
+ ratio: 1214.21,
43226
+ precision: 0.8478,
43227
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
43228
+ verdict: "USEFUL",
43229
+ _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).",
43230
+ aiSpecific: false,
43231
+ _v7Verdict: "USEFUL",
43232
+ _v7Lift: 859.38,
43233
+ _v7Recall: 34e-4,
43234
+ _v7FpRate: 1e-3,
43235
+ _v7Precision: 0.82,
43236
+ _v8Verdict: "USEFUL",
43237
+ _v8Lift: 68293.81
41105
43238
  },
41106
43239
  "wcag/missing-alt": {
41107
- recall: 0,
41108
- fpRate: 0,
41109
- ratio: 0,
41110
- precision: 0,
41111
- lastCalibratedAt: "2026-06-30T00:00:00Z",
41112
- verdict: "DORMANT",
41113
- defaultOff: true,
41114
- _calibrationNote: 'v0.16.0 ship \u2014 not in v7 per-rule table. Default-off until calibration data lands. Backed by: W3C (2023), *Web Content Accessibility Guidelines (WCAG) 2.2 \u2014 1.1.1 Non-text Content*, https://www.w3.org/TR/WCAG22/. (Every <img> needs alt text. Decorative: alt="". Informative: describe the image.)',
41115
- aiSpecific: false
43240
+ recall: 11e-4,
43241
+ fpRate: 7e-4,
43242
+ ratio: 935.33,
43243
+ precision: 0.6456,
43244
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
43245
+ verdict: "USEFUL",
43246
+ _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).",
43247
+ aiSpecific: false,
43248
+ _v7Verdict: "DORMANT",
43249
+ _v7Lift: 1,
43250
+ _v7Recall: 0,
43251
+ _v7FpRate: 0,
43252
+ _v7Precision: 0,
43253
+ _v8Verdict: "USEFUL",
43254
+ _v8Lift: 254.79
41116
43255
  },
41117
- "typo/placeholder-text": {
43256
+ "wcag/target-size": {
41118
43257
  recall: 0,
41119
43258
  fpRate: 0,
41120
43259
  ratio: 0,
41121
43260
  precision: 0,
41122
- lastCalibratedAt: "2026-06-30T00:00:00Z",
43261
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
41123
43262
  verdict: "DORMANT",
41124
- defaultOff: true,
41125
- _calibrationNote: "v0.16.0 ship \u2014 not in v7 per-rule table. Default-off until calibration data lands. Backed by: Nielsen, J. (2000), *Designing Web Usability* (placeholder copy as a top-10 trust erosion signal); Krug, S. (2000), *Don't Make Me Think*, 2nd ed. (TODO/placeholder text in shipped UI signals incomplete work.)",
41126
- aiSpecific: false
43263
+ _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.",
43264
+ aiSpecific: false,
43265
+ _v7Verdict: "DORMANT",
43266
+ _v7Lift: 0,
43267
+ _v7Recall: 0,
43268
+ _v7FpRate: 0,
43269
+ _v7Precision: 0,
43270
+ _v8Verdict: "DORMANT",
43271
+ _v8Lift: 1,
43272
+ defaultOff: true
41127
43273
  }
41128
43274
  };
41129
43275
 
@@ -41162,7 +43308,6 @@ async function scanFile(filePath, config, registry, cwd = process.cwd()) {
41162
43308
  ".kt",
41163
43309
  ".kts",
41164
43310
  ".dart",
41165
- ".rs",
41166
43311
  ".cpp",
41167
43312
  ".cc",
41168
43313
  ".cxx",