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,415 @@
1
1
  var __defProp = Object.defineProperty;
2
+ var __getOwnPropNames = Object.getOwnPropertyNames;
3
+ var __esm = (fn, res) => function __init() {
4
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
5
+ };
2
6
  var __export = (target, all) => {
3
7
  for (var name in all)
4
8
  __defProp(target, name, { get: all[name], enumerable: true });
5
9
  };
6
10
 
11
+ // src/engine/parser-rust.ts
12
+ import Parser from "tree-sitter";
13
+ import Rust from "tree-sitter-rust";
14
+ function getRustParser() {
15
+ if (cachedParser) return { ok: true, parser: cachedParser };
16
+ if (loadError) return { ok: false, error: loadError };
17
+ try {
18
+ rustLanguage = Rust;
19
+ if (!rustLanguage || typeof rustLanguage !== "object") {
20
+ throw new Error("tree-sitter-rust: language export is missing or malformed");
21
+ }
22
+ const parser = new Parser();
23
+ parser.setLanguage(rustLanguage);
24
+ cachedParser = parser;
25
+ return { ok: true, parser };
26
+ } catch (err) {
27
+ loadError = err instanceof Error ? err : new Error(String(err));
28
+ return { ok: false, error: loadError };
29
+ }
30
+ }
31
+ function effectiveParser() {
32
+ if (forcedFailure) return { ok: false, error: forcedFailure };
33
+ return getRustParser();
34
+ }
35
+ function parseRust(source) {
36
+ const result = effectiveParser();
37
+ if (!result.ok) return null;
38
+ if (!source || source.trim() === "") return null;
39
+ try {
40
+ const rawTree = result.parser.parse(source);
41
+ if (!rawTree) return null;
42
+ const tree = rawTree;
43
+ if (!tree || !tree.rootNode) return null;
44
+ if (tree.rootNode.type === "ERROR" && tree.rootNode.childCount === 0) {
45
+ return null;
46
+ }
47
+ return tree;
48
+ } catch {
49
+ return null;
50
+ }
51
+ }
52
+ function isRustParserAvailable() {
53
+ const result = getRustParser();
54
+ return result.ok;
55
+ }
56
+ var cachedParser, rustLanguage, loadError, forcedFailure;
57
+ var init_parser_rust = __esm({
58
+ "src/engine/parser-rust.ts"() {
59
+ "use strict";
60
+ cachedParser = null;
61
+ rustLanguage = null;
62
+ loadError = null;
63
+ forcedFailure = null;
64
+ }
65
+ });
66
+
67
+ // src/engine/visitors/rust.ts
68
+ function parseRustFile(filePath, source, options = {}) {
69
+ const empty = {
70
+ imports: [],
71
+ functions: [],
72
+ structs: [],
73
+ traits: [],
74
+ impls: []
75
+ };
76
+ if (!isRustParserAvailable() || options.forceFallback) {
77
+ return empty;
78
+ }
79
+ const tree = parseRust(source);
80
+ if (!tree) return empty;
81
+ return walkRustTree(tree);
82
+ }
83
+ function walkRustTree(tree) {
84
+ const ctx = { inTestConfig: false };
85
+ const out = {
86
+ imports: [],
87
+ functions: [],
88
+ structs: [],
89
+ traits: [],
90
+ impls: []
91
+ };
92
+ walkChildren(tree.rootNode, ctx, out);
93
+ return out;
94
+ }
95
+ function walkChildren(node, ctx, out) {
96
+ for (let i = 0; i < node.namedChildCount; i++) {
97
+ const child = node.namedChild(i);
98
+ if (!child) continue;
99
+ visitNode(child, ctx, out);
100
+ }
101
+ }
102
+ function visitNode(node, ctx, out) {
103
+ const innerCtx = { ...ctx };
104
+ const attrState = readPrecedingAttributes(node);
105
+ switch (node.type) {
106
+ case "use_declaration": {
107
+ out.imports.push(extractUse(node));
108
+ return;
109
+ }
110
+ case "function_item": {
111
+ const isMethod = isInImplBlock(node);
112
+ out.functions.push(extractFunction(node, attrState, innerCtx.inTestConfig, isMethod));
113
+ walkChildren(getField(node, "body") ?? node, innerCtx, out);
114
+ return;
115
+ }
116
+ case "struct_item": {
117
+ out.structs.push(extractStruct(node, attrState));
118
+ const body = getField(node, "body");
119
+ if (body) walkChildren(body, innerCtx, out);
120
+ return;
121
+ }
122
+ case "trait_item": {
123
+ out.traits.push(extractTrait(node, attrState));
124
+ const body = getField(node, "body");
125
+ if (body) walkChildren(body, innerCtx, out);
126
+ return;
127
+ }
128
+ case "impl_item": {
129
+ const implEntry = extractImpl(node, attrState, innerCtx);
130
+ out.impls.push(implEntry.entry);
131
+ const body = getField(node, "body");
132
+ if (body) walkChildren(body, innerCtx, out);
133
+ return;
134
+ }
135
+ case "mod_item": {
136
+ const modIsTest = innerCtx.inTestConfig || attrState.isTestCfg;
137
+ const modCtx = { ...innerCtx, inTestConfig: modIsTest };
138
+ const body = getField(node, "body");
139
+ if (body) walkChildren(body, modCtx, out);
140
+ return;
141
+ }
142
+ default: {
143
+ for (let i = 0; i < node.namedChildCount; i++) {
144
+ const child = node.namedChild(i);
145
+ if (child) visitNode(child, innerCtx, out);
146
+ }
147
+ }
148
+ }
149
+ }
150
+ function readPrecedingAttributes(node) {
151
+ const state = {
152
+ isTestCfg: false,
153
+ isTest: false,
154
+ isPub: false,
155
+ derives: []
156
+ };
157
+ const parent = node.parent;
158
+ if (!parent) return state;
159
+ for (let i = 0; i < parent.namedChildCount; i++) {
160
+ const sibling = parent.namedChild(i);
161
+ if (!sibling || sibling === node) continue;
162
+ if (sibling.endIndex > node.startIndex) continue;
163
+ if (sibling.type !== "attribute_item") continue;
164
+ decodeAttribute(sibling, state);
165
+ }
166
+ return state;
167
+ }
168
+ function decodeAttribute(attr, state) {
169
+ for (let i = 0; i < attr.namedChildCount; i++) {
170
+ const child = attr.namedChild(i);
171
+ if (!child || child.type !== "attribute") continue;
172
+ const name = firstIdentifier(child);
173
+ if (!name) continue;
174
+ if (name === "cfg") {
175
+ const cfgText = child.text;
176
+ if (/\btest\b/.test(cfgText) && !/\bnot\(test\)/.test(cfgText)) {
177
+ state.isTestCfg = true;
178
+ }
179
+ } else if (name === "test") {
180
+ state.isTest = true;
181
+ } else if (name === "derive") {
182
+ for (let j = 0; j < child.namedChildCount; j++) {
183
+ const inner = child.namedChild(j);
184
+ if (inner) {
185
+ const matches = inner.text.matchAll(/\b([A-Z][A-Za-z0-9_]*)\b/g);
186
+ for (const m of matches) state.derives.push(m[1]);
187
+ }
188
+ }
189
+ }
190
+ }
191
+ }
192
+ function firstIdentifier(node) {
193
+ const text = node.text;
194
+ const idMatch = text.match(/^([a-zA-Z_][a-zA-Z0-9_]*)/);
195
+ return idMatch ? idMatch[1] : null;
196
+ }
197
+ function extractUse(node) {
198
+ const text = node.text;
199
+ const argument = node.namedChild(0);
200
+ const argField = node.childForFieldName("argument");
201
+ const path = argField?.text ?? argument?.text ?? "";
202
+ const names = [];
203
+ let isGlob = false;
204
+ const useListNode = findUseListNode(argument);
205
+ if (useListNode) {
206
+ for (let i = 0; i < useListNode.namedChildCount; i++) {
207
+ const item = useListNode.namedChild(i);
208
+ if (item.type === "use_wildcard") {
209
+ isGlob = true;
210
+ } else if (item.type === "identifier") {
211
+ names.push({ name: item.text });
212
+ } else if (item.type === "use_as_clause") {
213
+ const alias = item.childForFieldName("alias");
214
+ const binding = item.childForFieldName("path");
215
+ if (binding) {
216
+ names.push({ name: binding.text, alias: alias?.text });
217
+ } else {
218
+ names.push({ name: item.text });
219
+ }
220
+ } else if (item.type === "scoped_identifier") {
221
+ const idents = collectIdentifiers(item);
222
+ names.push({ name: idents[idents.length - 1] ?? item.text });
223
+ } else if (item.text.includes(" as ")) {
224
+ const [head, alias] = item.text.split(/\s+as\s+/);
225
+ names.push({ name: (head ?? "").trim(), alias: alias?.trim() });
226
+ } else {
227
+ names.push({ name: item.text });
228
+ }
229
+ }
230
+ } else if (argument?.type === "use_wildcard") {
231
+ isGlob = true;
232
+ } else if (argument) {
233
+ const idents = collectIdentifiers(argument);
234
+ const last = idents[idents.length - 1] ?? argument.text;
235
+ names.push({ name: last });
236
+ const asMatch = text.match(/\s+as\s+(\w+)\s*;?\s*$/);
237
+ if (asMatch) names[0].alias = asMatch[1];
238
+ }
239
+ return {
240
+ path: path.trim(),
241
+ names,
242
+ isGlob,
243
+ line: node.startPosition.row + 1,
244
+ column: node.startPosition.column
245
+ };
246
+ }
247
+ function extractFunction(node, attrs, inheritedTestConfig, isMethod) {
248
+ const nameNode = node.childForFieldName("name");
249
+ const name = nameNode?.text ?? "<anon>";
250
+ const params = node.childForFieldName("parameters");
251
+ const body = node.childForFieldName("body");
252
+ const visibilityMod = node.namedChild(0);
253
+ const isPublic = visibilityMod?.type === "visibility_modifier";
254
+ let receiver;
255
+ if (isMethod && params) {
256
+ const selfParam = findSelfParameter(params);
257
+ if (selfParam) receiver = selfParam.text;
258
+ }
259
+ const bodyLines = body ? body.endPosition.row - body.startPosition.row + 1 : 0;
260
+ const inTestConfig = inheritedTestConfig || attrs.isTest || attrs.isTestCfg || isFunctionAttrTest(node);
261
+ return {
262
+ name,
263
+ line: node.startPosition.row + 1,
264
+ column: node.startPosition.column,
265
+ isPublic,
266
+ isMethod,
267
+ receiver,
268
+ bodyLines,
269
+ inTestConfig
270
+ };
271
+ }
272
+ function extractStruct(node, attrs) {
273
+ const nameNode = node.childForFieldName("name");
274
+ return {
275
+ name: nameNode?.text ?? "<anon>",
276
+ line: node.startPosition.row + 1,
277
+ column: node.startPosition.column,
278
+ isPublic: hasVisibility(node),
279
+ isDerive: attrs.derives.length > 0,
280
+ derives: [...attrs.derives]
281
+ };
282
+ }
283
+ function extractTrait(node, _attrs) {
284
+ const nameNode = node.childForFieldName("name");
285
+ return {
286
+ name: nameNode?.text ?? "<anon>",
287
+ line: node.startPosition.row + 1,
288
+ column: node.startPosition.column,
289
+ isPublic: hasVisibility(node)
290
+ };
291
+ }
292
+ function extractImpl(node, _attrs, _ctx) {
293
+ const traitNode = node.childForFieldName("trait");
294
+ const typeNode = node.childForFieldName("type");
295
+ const typeText = typeNode?.text ?? "<anon>";
296
+ const traitText = traitNode?.text;
297
+ const body = node.childForFieldName("body");
298
+ const methods = [];
299
+ if (body) {
300
+ for (let i = 0; i < body.namedChildCount; i++) {
301
+ const child = body.namedChild(i);
302
+ if (child?.type === "function_item") {
303
+ const m = child.childForFieldName("name");
304
+ if (m) methods.push(m.text);
305
+ }
306
+ }
307
+ }
308
+ return {
309
+ entry: {
310
+ type: typeText,
311
+ trait: traitText ?? void 0,
312
+ methods,
313
+ line: node.startPosition.row + 1,
314
+ column: node.startPosition.column
315
+ }
316
+ };
317
+ }
318
+ function findUseListNode(argument) {
319
+ if (!argument) return null;
320
+ if (argument.type === "use_list") return argument;
321
+ if (argument.type === "scoped_use_list") {
322
+ for (let i = 0; i < argument.namedChildCount; i++) {
323
+ const c = argument.namedChild(i);
324
+ if (c?.type === "use_list") return c;
325
+ }
326
+ }
327
+ return null;
328
+ }
329
+ function getField(node, fieldName) {
330
+ return node.childForFieldName(fieldName);
331
+ }
332
+ function collectIdentifiers(node) {
333
+ const out = [];
334
+ for (let i = 0; i < node.namedChildCount; i++) {
335
+ const child = node.namedChild(i);
336
+ if (!child) continue;
337
+ if (child.type === "identifier" || child.type === "type_identifier") {
338
+ out.push(child.text);
339
+ } else if (child.type === "scoped_identifier" || child.type === "nested_identifier") {
340
+ out.push(...collectIdentifiers(child));
341
+ }
342
+ }
343
+ return out;
344
+ }
345
+ function hasVisibility(node) {
346
+ return node.namedChild(0)?.type === "visibility_modifier";
347
+ }
348
+ function isInImplBlock(node) {
349
+ for (let p = node.parent; p; p = p.parent) {
350
+ if (p.type === "impl_item") return true;
351
+ if (p.type === "function_item" || p.type === "source_file") return false;
352
+ }
353
+ return false;
354
+ }
355
+ function findSelfParameter(params) {
356
+ for (let i = 0; i < params.namedChildCount; i++) {
357
+ const child = params.namedChild(i);
358
+ if (child?.type === "self_parameter") return child;
359
+ }
360
+ return null;
361
+ }
362
+ function isFunctionAttrTest(node) {
363
+ void node;
364
+ return false;
365
+ }
366
+ var SERVICE_SUFFIXES, SERVICE_SUFFIX_GROUP, RUST_SERVICE_STRUCT_RE, RUST_SERVICE_IMPL_RE;
367
+ var init_rust = __esm({
368
+ "src/engine/visitors/rust.ts"() {
369
+ "use strict";
370
+ init_parser_rust();
371
+ SERVICE_SUFFIXES = [
372
+ "Service",
373
+ "Manager",
374
+ "Handler",
375
+ "Repository",
376
+ "Controller",
377
+ "Helper",
378
+ "Factory",
379
+ "Provider",
380
+ "Store",
381
+ "API",
382
+ "Client",
383
+ "Adapter",
384
+ "Resolver",
385
+ "Mapper",
386
+ "Transformer",
387
+ "Serializer",
388
+ "Validator",
389
+ "Strategy",
390
+ "Facade",
391
+ "Decorator",
392
+ "Observer",
393
+ "Builder",
394
+ "Command",
395
+ "Processor",
396
+ "Worker",
397
+ "Job",
398
+ "Actor",
399
+ "Executor"
400
+ ];
401
+ SERVICE_SUFFIX_GROUP = `(?:${SERVICE_SUFFIXES.join("|")})`;
402
+ RUST_SERVICE_STRUCT_RE = new RegExp(
403
+ `^(?:pub(?:\\(crate\\)|\\(super\\))?\\s+)?struct\\s+(\\w+?)${SERVICE_SUFFIX_GROUP}?\\b`,
404
+ "gm"
405
+ );
406
+ RUST_SERVICE_IMPL_RE = new RegExp(
407
+ `^impl(?:<[^>]+>)?\\s+(?:${SERVICE_SUFFIX_GROUP}\\s+for\\s+)?(\\w+?)${SERVICE_SUFFIX_GROUP}?\\b`,
408
+ "gm"
409
+ );
410
+ }
411
+ });
412
+
7
413
  // src/engine/worker.ts
8
414
  import { isMainThread, parentPort, workerData } from "worker_threads";
9
415
  import { extname as extname6 } from "path";
@@ -4239,7 +4645,7 @@ function parseBlankModule(source) {
4239
4645
  tsx: false,
4240
4646
  target: "es2022"
4241
4647
  });
4242
- return { ast, source: replaced };
4648
+ return { ast, source };
4243
4649
  }
4244
4650
  function parseScriptContent(content, isTypeScript) {
4245
4651
  if (isTypeScript) {
@@ -4325,8 +4731,16 @@ function parseSource(source, filePath) {
4325
4731
  // but no SWC support. Return a blank-padded empty module so
4326
4732
  // regex-only rules can still fire (markdown-leakage, comment-
4327
4733
  // ratio, etc.) without burning the parseError path.
4734
+ // v0.18.9: `.rs` is in the same bucket. The visitor layer
4735
+ // (`engine/visitors/rust.ts`) carries the tree-sitter-backed
4736
+ // parse + extractFacts attaches the result to `facts.v2.rustFile`.
4737
+ // The rule layer (`rules/rust/*.ts`) reads that field. parseBlankModule
4738
+ // lets the worker continue past the parser — without this, parseWithSwc
4739
+ // would throw on every .rs file, the worker would count it as a
4740
+ // parseError, and the v2-build's buildRustFileRecord would never run.
4328
4741
  case "py":
4329
4742
  case "go":
4743
+ case "rs":
4330
4744
  return parseBlankModule(source);
4331
4745
  default:
4332
4746
  return parseWithSwc(source, filePath);
@@ -6891,6 +7305,7 @@ function dispatchNode(node, parent, path, vctx) {
6891
7305
  }
6892
7306
 
6893
7307
  // src/engine/visitors/v2-build.ts
7308
+ init_rust();
6894
7309
  var TAILWIND_COLOR_RE = /^(?:bg|text|border|ring|from|to|via|fill|stroke)-([a-z]+-\d+|white|black|transparent|current|\[.+?\])$/;
6895
7310
  var TAILWIND_SPACING_RE = /^(?:[pm][xytrbl]?|gap|space-[xy])-(\d+(?:\.\d+)?)$/;
6896
7311
  var TAILWIND_RADIUS_RE = /^(?:rounded(?:-[a-z]+)?)-(.+)$/;
@@ -7071,9 +7486,60 @@ function buildV2Facts(facts, source, ext, framework, config, templateClassNames
7071
7486
  })),
7072
7487
  disabledRules: extractDisabledRules(source),
7073
7488
  templateClassNames,
7489
+ // v0.18.9 — populate the Rust AST record when the file is `.rs`.
7490
+ // Calling `parseRustFile` here keeps the dead-code detector's
7491
+ // import-binding pass a pure function over the same source the
7492
+ // walker saw. The native-binding guard lives inside
7493
+ // `parseRustFile` (returns an empty record when tree-sitter is
7494
+ // unavailable).
7495
+ rustFile: buildRustFileRecord(facts.filePath, source),
7074
7496
  _source: source
7075
7497
  };
7076
7498
  }
7499
+ function buildRustFileRecord(filePath, source) {
7500
+ if (!filePath.toLowerCase().endsWith(".rs")) return void 0;
7501
+ const structure = parseRustFile(filePath, source);
7502
+ return {
7503
+ imports: structure.imports.map((i) => ({
7504
+ path: i.path,
7505
+ names: i.names.map((n) => ({ name: n.name, ...n.alias ? { alias: n.alias } : {} })),
7506
+ isGlob: i.isGlob,
7507
+ line: i.line,
7508
+ column: i.column
7509
+ })),
7510
+ functions: structure.functions.map((f) => ({
7511
+ name: f.name,
7512
+ line: f.line,
7513
+ column: f.column,
7514
+ isPublic: f.isPublic,
7515
+ isMethod: f.isMethod,
7516
+ ...f.receiver ? { receiver: f.receiver } : {},
7517
+ bodyLines: f.bodyLines,
7518
+ inTestConfig: f.inTestConfig
7519
+ })),
7520
+ structs: structure.structs.map((s) => ({
7521
+ name: s.name,
7522
+ line: s.line,
7523
+ column: s.column,
7524
+ isPublic: s.isPublic,
7525
+ isDerive: s.isDerive,
7526
+ derives: [...s.derives]
7527
+ })),
7528
+ traits: structure.traits.map((t) => ({
7529
+ name: t.name,
7530
+ line: t.line,
7531
+ column: t.column,
7532
+ isPublic: t.isPublic
7533
+ })),
7534
+ impls: structure.impls.map((ip) => ({
7535
+ ...ip.trait ? { trait: ip.trait } : {},
7536
+ type: ip.type,
7537
+ methods: [...ip.methods],
7538
+ line: ip.line,
7539
+ column: ip.column
7540
+ }))
7541
+ };
7542
+ }
7077
7543
  function splitFilePath(filePath) {
7078
7544
  const baseName = filePath.split("/").pop() ?? filePath;
7079
7545
  const dotIdx = baseName.lastIndexOf(".");
@@ -34575,9 +35041,43 @@ var unusedImportRule = createRule({
34575
35041
  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.`
34576
35042
  });
34577
35043
  }
35044
+ if (facts.v2.rustFile) {
35045
+ const strippedSource = stripUseDeclarations(facts.v2._source ?? "");
35046
+ const referenced = collectRustReferencedNames(strippedSource);
35047
+ for (const imp of facts.v2.rustFile.imports) {
35048
+ for (const nameEntry of imp.names) {
35049
+ if (referenced.has(nameEntry.name)) continue;
35050
+ const source = ` from '${imp.path}'`;
35051
+ issues.push({
35052
+ ruleId: "dead/unused-import",
35053
+ category: "logic",
35054
+ severity: "low",
35055
+ aiSpecific: true,
35056
+ message: `Unused import: '${nameEntry.name}'${source}`,
35057
+ line: imp.line,
35058
+ column: imp.column,
35059
+ 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)].`
35060
+ });
35061
+ }
35062
+ }
35063
+ }
34578
35064
  return issues;
34579
35065
  }
34580
35066
  });
35067
+ function collectRustReferencedNames(source) {
35068
+ const out = /* @__PURE__ */ new Set();
35069
+ for (const m of source.matchAll(/\b([A-Za-z_][A-Za-z0-9_]*)\b/g)) {
35070
+ out.add(m[1]);
35071
+ }
35072
+ return out;
35073
+ }
35074
+ function stripUseDeclarations(source) {
35075
+ let out = source;
35076
+ out = out.replace(/^\s*use\s+[\s\S]*?;\s*$/gm, "");
35077
+ out = out.replace(/\/\/[^\n]*/g, "");
35078
+ out = out.replace(/\/\*[\s\S]*?\*\//g, "");
35079
+ return out;
35080
+ }
34581
35081
 
34582
35082
  // src/rules/dead/unused-local.ts
34583
35083
  var SKIP_NAMES = /* @__PURE__ */ new Set(["React", "_"]);
@@ -34738,6 +35238,9 @@ var expiredCodeExampleRule = createRule({
34738
35238
  const issues = [];
34739
35239
  const source = facts.v2?._source;
34740
35240
  if (!source) return issues;
35241
+ const packages = declaredPackages(context.cwd);
35242
+ const packageName = context.packageName;
35243
+ if (packageName) packages.add(packageName);
34741
35244
  const blocks = extractFencedCodeBlocks(source);
34742
35245
  for (const block of blocks) {
34743
35246
  if (!CODE_LANGS.has(block.lang)) continue;
@@ -34745,7 +35248,7 @@ var expiredCodeExampleRule = createRule({
34745
35248
  const imports = extractImports(block.body);
34746
35249
  for (const imp of imports) {
34747
35250
  const pkgName = stripSubpath(imp);
34748
- if (context.packages.has(pkgName)) continue;
35251
+ if (packages.has(pkgName)) continue;
34749
35252
  issues.push({
34750
35253
  ruleId: "docs/expired-code-example",
34751
35254
  category: "docs",
@@ -34766,6 +35269,7 @@ var expiredCodeExampleRule = createRule({
34766
35269
  import { readFileSync as readFileSync4, readdirSync, existsSync as existsSync2 } from "fs";
34767
35270
  import { join as join5, extname as extname3 } from "path";
34768
35271
  var RESERVED = /* @__PURE__ */ new Set([
35272
+ // JS reserved words
34769
35273
  "true",
34770
35274
  "false",
34771
35275
  "null",
@@ -34865,7 +35369,472 @@ var RESERVED = /* @__PURE__ */ new Set([
34865
35369
  "next",
34866
35370
  "vue",
34867
35371
  "angular",
34868
- "svelte"
35372
+ "svelte",
35373
+ // Framework / runtime names
35374
+ "html",
35375
+ "astro",
35376
+ "python",
35377
+ "jvm",
35378
+ "kotlin",
35379
+ "swift",
35380
+ "dart",
35381
+ "ruby",
35382
+ "rust",
35383
+ "cpp",
35384
+ "go",
35385
+ "java",
35386
+ "php",
35387
+ "php-html",
35388
+ "csharp",
35389
+ "typescript",
35390
+ "javascript",
35391
+ "jsx",
35392
+ "tsx",
35393
+ "mjs",
35394
+ "cjs",
35395
+ "esnext",
35396
+ "es6",
35397
+ "es2022",
35398
+ "es2023",
35399
+ "esm",
35400
+ "cjs",
35401
+ "umd",
35402
+ "amd",
35403
+ "commonjs",
35404
+ "require",
35405
+ "module",
35406
+ "exports",
35407
+ "define",
35408
+ "global",
35409
+ "window",
35410
+ "document",
35411
+ "process",
35412
+ "console",
35413
+ "buffer",
35414
+ "stream",
35415
+ "fetch",
35416
+ "axios",
35417
+ "express",
35418
+ "fastify",
35419
+ "koa",
35420
+ "hapi",
35421
+ "nextjs",
35422
+ "nuxt",
35423
+ "remix",
35424
+ "gatsby",
35425
+ "sveltekit",
35426
+ "solid",
35427
+ "preact",
35428
+ "qwik",
35429
+ "lit",
35430
+ "stencil",
35431
+ "marko",
35432
+ "alpine",
35433
+ "stimulus",
35434
+ "turbo",
35435
+ "hotwire",
35436
+ // Models / providers
35437
+ "gpt",
35438
+ "claude",
35439
+ "gpt-3",
35440
+ "gpt-3.5",
35441
+ "gpt-4",
35442
+ "gpt-oss",
35443
+ "haiku",
35444
+ "sonnet",
35445
+ "opus",
35446
+ "aider",
35447
+ "tabby",
35448
+ "copilot",
35449
+ "cursor",
35450
+ "windsurf",
35451
+ "devin",
35452
+ "claude-code",
35453
+ // LLM-detection lingo
35454
+ "heuristic",
35455
+ "heuristics",
35456
+ "calibrate",
35457
+ "calibration",
35458
+ "calibrator",
35459
+ "corpus",
35460
+ "baseline",
35461
+ "baselines",
35462
+ "corpus-baselines",
35463
+ "lift",
35464
+ "recall",
35465
+ "precision",
35466
+ "fpRate",
35467
+ "ratio",
35468
+ "verdict",
35469
+ "USEFUL",
35470
+ "NOISY",
35471
+ "INVERTED",
35472
+ "HYGIENE",
35473
+ "DORMANT",
35474
+ "OK",
35475
+ "aiSpecific",
35476
+ "defaultOff",
35477
+ // Common slop-audit verbs/nouns
35478
+ "commit",
35479
+ "push",
35480
+ "reset",
35481
+ "rebase",
35482
+ "merge",
35483
+ "cherry-pick",
35484
+ "revert",
35485
+ "scan",
35486
+ "parse",
35487
+ "build",
35488
+ "test",
35489
+ "lint",
35490
+ "format",
35491
+ "check",
35492
+ "audit",
35493
+ "fix",
35494
+ "patch",
35495
+ "diff",
35496
+ "pr",
35497
+ "ci",
35498
+ "cd",
35499
+ "gh",
35500
+ "npm",
35501
+ "npx",
35502
+ "pnpm",
35503
+ "yaml",
35504
+ "json",
35505
+ "toml",
35506
+ "csv",
35507
+ "md",
35508
+ "mdx",
35509
+ "sh",
35510
+ "bash",
35511
+ "zsh",
35512
+ "fish",
35513
+ "ascii",
35514
+ "utf8",
35515
+ "utf-8",
35516
+ "base64",
35517
+ "hex",
35518
+ "binary",
35519
+ "text",
35520
+ // Common design / ui terms
35521
+ "flex",
35522
+ "grid",
35523
+ "auto",
35524
+ "min",
35525
+ "max",
35526
+ "fill",
35527
+ "stretch",
35528
+ "wrap",
35529
+ "nowrap",
35530
+ "inline",
35531
+ "block",
35532
+ "hidden",
35533
+ "visible",
35534
+ "static",
35535
+ "fixed",
35536
+ "absolute",
35537
+ "relative",
35538
+ "sticky",
35539
+ "pointer",
35540
+ "cursor",
35541
+ "focus",
35542
+ "hover",
35543
+ "active",
35544
+ "disabled",
35545
+ "readonly",
35546
+ "primary",
35547
+ "secondary",
35548
+ "tertiary",
35549
+ "success",
35550
+ "warning",
35551
+ "danger",
35552
+ "info",
35553
+ "muted",
35554
+ "sm",
35555
+ "md",
35556
+ "lg",
35557
+ "xl",
35558
+ "xxl",
35559
+ "xs",
35560
+ "2xl",
35561
+ "3xl",
35562
+ "4xl",
35563
+ // Math / types
35564
+ "array",
35565
+ "map",
35566
+ "set",
35567
+ "weakmap",
35568
+ "weakset",
35569
+ "object",
35570
+ "string",
35571
+ "number",
35572
+ "boolean",
35573
+ "bigint",
35574
+ "symbol",
35575
+ "null",
35576
+ "undefined",
35577
+ "any",
35578
+ "unknown",
35579
+ "never",
35580
+ "void",
35581
+ "readonly",
35582
+ "private",
35583
+ "public",
35584
+ "protected",
35585
+ "static",
35586
+ "abstract",
35587
+ "async",
35588
+ "generator",
35589
+ "iterator",
35590
+ "iterable",
35591
+ "promise",
35592
+ "observable",
35593
+ // Auth / domain
35594
+ "admin",
35595
+ "user",
35596
+ "guest",
35597
+ "anonymous",
35598
+ "authenticated",
35599
+ "unauthenticated",
35600
+ "jwt",
35601
+ "oauth",
35602
+ "oidc",
35603
+ "saml",
35604
+ "csrf",
35605
+ "xss",
35606
+ "sql",
35607
+ "nosql",
35608
+ "orm",
35609
+ "prisma",
35610
+ "drizzle",
35611
+ "sequelize",
35612
+ "mongoose",
35613
+ "redis",
35614
+ "postgres",
35615
+ "mysql",
35616
+ "sqlite",
35617
+ "kafka",
35618
+ "rabbitmq",
35619
+ "graphql",
35620
+ "rest",
35621
+ "grpc",
35622
+ "websocket",
35623
+ // slop-audit specific
35624
+ "slopbrick",
35625
+ "usebrick",
35626
+ "deadcode",
35627
+ "unused",
35628
+ "orphan",
35629
+ "zombie",
35630
+ "blocker",
35631
+ "warning",
35632
+ "info",
35633
+ "error",
35634
+ "verbose",
35635
+ "debug",
35636
+ "silly",
35637
+ "p50",
35638
+ "p90",
35639
+ "p95",
35640
+ "p99",
35641
+ "min",
35642
+ "max",
35643
+ "avg",
35644
+ "mean",
35645
+ "median",
35646
+ "ratchet",
35647
+ "tier",
35648
+ "composite",
35649
+ "fitness",
35650
+ "fpr",
35651
+ "tpr",
35652
+ "roc",
35653
+ "should",
35654
+ "could",
35655
+ "would",
35656
+ "might",
35657
+ "must",
35658
+ "shall",
35659
+ "may",
35660
+ "can",
35661
+ "todo",
35662
+ "fixme",
35663
+ "xxx",
35664
+ "hack",
35665
+ "note",
35666
+ "warning",
35667
+ "attention",
35668
+ "h1",
35669
+ "h2",
35670
+ "h3",
35671
+ "h4",
35672
+ "h5",
35673
+ "h6",
35674
+ "strong",
35675
+ "em",
35676
+ "b",
35677
+ "i",
35678
+ "u",
35679
+ "true",
35680
+ "false",
35681
+ "yes",
35682
+ "no",
35683
+ "on",
35684
+ "off",
35685
+ "enable",
35686
+ "disable",
35687
+ "ltr",
35688
+ "rtl",
35689
+ "auto",
35690
+ "start",
35691
+ "end",
35692
+ "center",
35693
+ "baseline",
35694
+ "stretch",
35695
+ "rounded",
35696
+ "sharp",
35697
+ "outline",
35698
+ "ghost",
35699
+ "link",
35700
+ "filled",
35701
+ "row",
35702
+ "col",
35703
+ "gap",
35704
+ "pad",
35705
+ "margin",
35706
+ "padding",
35707
+ "border",
35708
+ "shadow",
35709
+ "transparent",
35710
+ "currentcolor",
35711
+ "inherit",
35712
+ "initial",
35713
+ "unset",
35714
+ "revert",
35715
+ "hover",
35716
+ "focus",
35717
+ "active",
35718
+ "disabled",
35719
+ "checked",
35720
+ "indeterminate",
35721
+ "open",
35722
+ "close",
35723
+ "expanded",
35724
+ "collapsed",
35725
+ "selected",
35726
+ "pressed",
35727
+ // Web/CSS
35728
+ "div",
35729
+ "span",
35730
+ "p",
35731
+ "a",
35732
+ "img",
35733
+ "ul",
35734
+ "ol",
35735
+ "li",
35736
+ "table",
35737
+ "tr",
35738
+ "td",
35739
+ "th",
35740
+ "thead",
35741
+ "tbody",
35742
+ "tfoot",
35743
+ "caption",
35744
+ "figure",
35745
+ "figcaption",
35746
+ "main",
35747
+ "section",
35748
+ "article",
35749
+ "aside",
35750
+ "header",
35751
+ "footer",
35752
+ "nav",
35753
+ "form",
35754
+ "input",
35755
+ "button",
35756
+ "select",
35757
+ "option",
35758
+ "textarea",
35759
+ "label",
35760
+ "fieldset",
35761
+ "legend",
35762
+ "details",
35763
+ "summary",
35764
+ "dialog",
35765
+ "menu",
35766
+ "menuitem",
35767
+ "template",
35768
+ "slot",
35769
+ "picture",
35770
+ "source",
35771
+ "track",
35772
+ "video",
35773
+ "audio",
35774
+ "canvas",
35775
+ "svg",
35776
+ "iframe",
35777
+ "embed",
35778
+ "object",
35779
+ "portal",
35780
+ // Common business terms
35781
+ "api",
35782
+ "cli",
35783
+ "ui",
35784
+ "ux",
35785
+ "sdk",
35786
+ "ide",
35787
+ "cli",
35788
+ "docs",
35789
+ "doc",
35790
+ "blog",
35791
+ "post",
35792
+ "page",
35793
+ "view",
35794
+ "tab",
35795
+ "panel",
35796
+ "card",
35797
+ "list",
35798
+ "grid",
35799
+ "form",
35800
+ "modal",
35801
+ "menu",
35802
+ "button",
35803
+ "icon",
35804
+ "avatar",
35805
+ "badge",
35806
+ "chip",
35807
+ "tooltip",
35808
+ "popover",
35809
+ "dropdown",
35810
+ "banner",
35811
+ "alert",
35812
+ "toast",
35813
+ "notification",
35814
+ "drawer",
35815
+ "sidebar",
35816
+ "navbar",
35817
+ "header",
35818
+ "footer",
35819
+ "hero",
35820
+ "cta",
35821
+ "cta-primary",
35822
+ "cta-secondary",
35823
+ "pricing",
35824
+ "price",
35825
+ "cost",
35826
+ "rate",
35827
+ "percent",
35828
+ "pct",
35829
+ "count",
35830
+ "total",
35831
+ "small",
35832
+ "medium",
35833
+ "large",
35834
+ "xl",
35835
+ "xxl",
35836
+ "tiny",
35837
+ "huge"
34869
35838
  ]);
34870
35839
  var SOURCE_EXTS = /* @__PURE__ */ new Set([".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"]);
34871
35840
  var SOURCE_ROOTS = ["src", "lib", "app", "components"];
@@ -34903,7 +35872,12 @@ function collectExports(cwd) {
34903
35872
  /\bexport\s+class\s+([A-Za-z_$][\w$]*)/g,
34904
35873
  /\bexport\s+interface\s+([A-Za-z_$][\w$]*)/g,
34905
35874
  /\bexport\s+type\s+([A-Za-z_$][\w$]*)/g,
34906
- /\bexport\s+default\s+(?:function\s+|class\s+)?([A-Za-z_$][\w$]*)/g
35875
+ /\bexport\s+default\s+(?:function\s+|class\s+)?([A-Za-z_$][\w$]*)/g,
35876
+ // v0.18.6: also collect field names from `export interface` and
35877
+ // `export type` declarations. Without this, fields like
35878
+ // `crossFileDrift`, `aiQuality`, `engineeringHygiene` are
35879
+ // flagged as stale even though they're valid type fields.
35880
+ /^\s*(?:readonly\s+)?([A-Za-z_$][\w$]*)\s*[?:]/gm
34907
35881
  ]) {
34908
35882
  let m;
34909
35883
  while ((m = re.exec(source)) !== null) {
@@ -34914,6 +35888,21 @@ function collectExports(cwd) {
34914
35888
  }
34915
35889
  return out;
34916
35890
  }
35891
+ function looksLikeProseLabel(inside) {
35892
+ const trimmed = inside.trim();
35893
+ if (trimmed.length === 0) return false;
35894
+ if (trimmed.startsWith("`") || trimmed.startsWith("/")) return true;
35895
+ if (trimmed.includes("`")) return true;
35896
+ if (/\d+\s+[a-z]/i.test(trimmed)) return true;
35897
+ const parts = trimmed.split(",").map((s) => s.trim());
35898
+ if (parts.length >= 3) {
35899
+ const allNumeric = parts.every((p) => /^\d+\.?\d*$/.test(p));
35900
+ if (!allNumeric) return true;
35901
+ }
35902
+ if (trimmed.length > 40 && !trimmed.includes(",")) return true;
35903
+ if (trimmed.includes("\u2014") || trimmed.includes("\u2013")) return true;
35904
+ return false;
35905
+ }
34917
35906
  var staleFunctionReferenceRule = createRule({
34918
35907
  id: "docs/stale-function-reference",
34919
35908
  category: "docs",
@@ -34933,8 +35922,39 @@ var staleFunctionReferenceRule = createRule({
34933
35922
  if (text.length < 3) continue;
34934
35923
  if (RESERVED.has(text.toLowerCase())) continue;
34935
35924
  if (context.exports.has(text)) continue;
34936
- const end = Math.min(source.length, span.index + text.length + 50);
34937
- if (!/\(/.test(source.slice(span.index, end))) continue;
35925
+ const lineEnd = source.indexOf("\n", span.index);
35926
+ const restOfLine = source.slice(
35927
+ span.index,
35928
+ lineEnd === -1 ? source.length : lineEnd
35929
+ );
35930
+ const closeTick = restOfLine.indexOf("`", 1);
35931
+ if (closeTick === -1) continue;
35932
+ const afterTick = restOfLine.slice(closeTick + 1);
35933
+ const directCall = /^\s*\(/.test(afterTick);
35934
+ let identifierRepeats = false;
35935
+ if (!directCall) {
35936
+ const afterSpan = restOfLine.slice(closeTick + 1);
35937
+ const needle = text + "(";
35938
+ identifierRepeats = afterSpan.indexOf(needle) !== -1;
35939
+ }
35940
+ if (!directCall && !identifierRepeats) continue;
35941
+ const beforeTickIdx = span.index - 1;
35942
+ const beforeChar = beforeTickIdx >= 0 ? source[beforeTickIdx] : "";
35943
+ if (beforeChar === "." || beforeChar === "|") continue;
35944
+ const parenStart = restOfLine.indexOf("(", closeTick);
35945
+ const parenEnd = restOfLine.indexOf(")", parenStart);
35946
+ if (parenStart !== -1 && parenEnd !== -1) {
35947
+ const inside = restOfLine.slice(parenStart + 1, parenEnd);
35948
+ const trimmed = inside.trim();
35949
+ if (looksLikeProseLabel(inside)) continue;
35950
+ 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(
35951
+ inside
35952
+ ) || // Short single-word label (≤ 24 chars, no `,`,
35953
+ // doesn't look like a function arg). Real function
35954
+ // calls are usually longer or contain commas.
35955
+ trimmed.length > 0 && trimmed.length <= 24 && !trimmed.includes(",") && /[a-zA-Z]/.test(trimmed));
35956
+ if (looksLikeTypeAnnotation) continue;
35957
+ }
34938
35958
  issues.push({
34939
35959
  ruleId: "docs/stale-function-reference",
34940
35960
  category: "docs",
@@ -35006,7 +36026,33 @@ var ENGLISH_WORD_DENYLIST = /* @__PURE__ */ new Set([
35006
36026
  "jsx",
35007
36027
  "ok",
35008
36028
  "no",
35009
- "yes"
36029
+ "yes",
36030
+ // v0.18.6: common English adjectives / adverbs that frequently
36031
+ // appear in backticked prose but are not package names.
36032
+ "aspirational",
36033
+ "concrete",
36034
+ "abstract",
36035
+ "inline",
36036
+ "exposed",
36037
+ "deprecated",
36038
+ "experimental",
36039
+ "stable",
36040
+ "beta",
36041
+ "alpha",
36042
+ "wip",
36043
+ "draft",
36044
+ "final",
36045
+ "shim",
36046
+ "polyfill",
36047
+ "stub",
36048
+ "mock",
36049
+ "fake",
36050
+ "real",
36051
+ "false",
36052
+ "true",
36053
+ "optional",
36054
+ "required",
36055
+ "default"
35010
36056
  ]);
35011
36057
  var stalePackageReferenceRule = createRule({
35012
36058
  id: "docs/stale-package-reference",
@@ -35168,7 +36214,9 @@ var brokenLinkRule = createRule({
35168
36214
  if (target.startsWith("#")) continue;
35169
36215
  if (target.startsWith("//")) continue;
35170
36216
  if (target.startsWith("/")) continue;
35171
- const resolved = join7(docDir, target);
36217
+ const filePart = target.split("#")[0] ?? target;
36218
+ if (filePart === "") continue;
36219
+ const resolved = join7(docDir, filePart);
35172
36220
  if (existsSync4(resolved)) continue;
35173
36221
  issues.push({
35174
36222
  ruleId: "docs/broken-link",
@@ -36942,6 +37990,326 @@ var uxPatternFragmentationRule = createRule({
36942
37990
  }
36943
37991
  });
36944
37992
 
37993
+ // src/rules/rust/stringly-typed.ts
37994
+ var SUSPECT_PARAM_NAMES = /* @__PURE__ */ new Set([
37995
+ "kind",
37996
+ "type",
37997
+ "mode",
37998
+ "event",
37999
+ "status",
38000
+ "category",
38001
+ "action",
38002
+ "state",
38003
+ "level",
38004
+ "role",
38005
+ "tier",
38006
+ "phase",
38007
+ "tag",
38008
+ "format",
38009
+ "shape",
38010
+ "direction",
38011
+ "side",
38012
+ "method"
38013
+ ]);
38014
+ var MAX_VARIANT_COUNT = 32;
38015
+ var rustStringlyTypedRule = createRule({
38016
+ id: "rust/stringly-typed",
38017
+ category: "logic",
38018
+ severity: "medium",
38019
+ aiSpecific: true,
38020
+ description: "String / &str parameter where a typed enum exists in the same file",
38021
+ create(_context) {
38022
+ return {};
38023
+ },
38024
+ analyze(_context, facts) {
38025
+ const issues = [];
38026
+ if (!facts.v2?.rustFile) return issues;
38027
+ const source = facts.v2._source ?? "";
38028
+ if (!source) return issues;
38029
+ const lineOffsets = buildLineOffsets2(source);
38030
+ const enumCandidates = collectEnumCandidates(source);
38031
+ if (enumCandidates.length === 0) return issues;
38032
+ for (const fn of facts.v2.rustFile.functions) {
38033
+ const paramText = extractParameterText(source, lineOffsets, fn);
38034
+ if (!paramText) continue;
38035
+ const matches = scanForStringlyParams(paramText);
38036
+ if (matches.length === 0) continue;
38037
+ issues.push({
38038
+ ruleId: "rust/stringly-typed",
38039
+ category: "logic",
38040
+ severity: "medium",
38041
+ aiSpecific: true,
38042
+ 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`,
38043
+ line: fn.line,
38044
+ column: fn.column,
38045
+ 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.`
38046
+ });
38047
+ }
38048
+ return issues;
38049
+ }
38050
+ });
38051
+ function collectEnumCandidates(source) {
38052
+ const out = [];
38053
+ const enumRe = /^(?:pub(?:\([^)]+\))?\s+)?enum\s+(\w+)\s*\{([^}]*)\}/gm;
38054
+ for (const m of source.matchAll(enumRe)) {
38055
+ const body = m[2] ?? "";
38056
+ const variants = body.split(/,(?![^()]*\))/).map((s) => s.trim()).filter((s) => /^[A-Za-z_][A-Za-z0-9_]*$/.test(s.split(/\s+/)[0] ?? ""));
38057
+ if (variants.length > MAX_VARIANT_COUNT) continue;
38058
+ if (variants.length < 2) continue;
38059
+ out.push({ name: m[1], variantCount: variants.length, line: lineOfMatch(source, m.index ?? 0) });
38060
+ }
38061
+ return out;
38062
+ }
38063
+ function lineOfMatch(source, index) {
38064
+ let line = 1;
38065
+ for (let i = 0; i < index && i < source.length; i++) {
38066
+ if (source[i] === "\n") line++;
38067
+ }
38068
+ return line;
38069
+ }
38070
+ function buildLineOffsets2(source) {
38071
+ const out = [0];
38072
+ for (let i = 0; i < source.length; i++) {
38073
+ if (source[i] === "\n") out.push(i + 1);
38074
+ }
38075
+ return out;
38076
+ }
38077
+ function extractParameterText(source, lineOffsets, fn) {
38078
+ const start = lineOffsets[Math.max(0, fn.line - 1)] ?? 0;
38079
+ const head = source.slice(start, start + 400);
38080
+ const openIdx = head.indexOf("(");
38081
+ if (openIdx < 0) return "";
38082
+ let closeIdx = -1;
38083
+ let depth = 0;
38084
+ for (let i = openIdx; i < head.length; i++) {
38085
+ if (head[i] === "(") depth++;
38086
+ else if (head[i] === ")") {
38087
+ depth--;
38088
+ if (depth === 0) {
38089
+ closeIdx = i;
38090
+ break;
38091
+ }
38092
+ }
38093
+ }
38094
+ if (closeIdx < 0) return "";
38095
+ return head.slice(openIdx + 1, closeIdx);
38096
+ }
38097
+ function scanForStringlyParams(paramText) {
38098
+ const out = [];
38099
+ for (const m of paramText.matchAll(
38100
+ /\b([a-z_][a-zA-Z0-9_]*)\s*:\s*(&\s*(?:mut\s+)?(?:str|String)\b)/g
38101
+ )) {
38102
+ const name = m[1];
38103
+ const type = m[2];
38104
+ if (!SUSPECT_PARAM_NAMES.has(name)) continue;
38105
+ out.push({ name, type });
38106
+ }
38107
+ return out;
38108
+ }
38109
+
38110
+ // src/rules/rust/todo-macro.ts
38111
+ init_parser_rust();
38112
+ var TODO_MACROS = /* @__PURE__ */ new Set(["todo", "unimplemented", "todo_unimplemented"]);
38113
+ var rustTodoMacroRule = createRule({
38114
+ id: "rust/todo-macro",
38115
+ category: "logic",
38116
+ severity: "medium",
38117
+ aiSpecific: true,
38118
+ description: "todo!() / unimplemented!() macro invocation in production code",
38119
+ create(_context) {
38120
+ return {};
38121
+ },
38122
+ analyze(_context, facts) {
38123
+ const issues = [];
38124
+ if (!facts.v2?.rustFile) return issues;
38125
+ const source = facts.v2._source ?? "";
38126
+ if (!source) return issues;
38127
+ const tree = parseRust(source);
38128
+ if (!tree) return issues;
38129
+ const testScopes = /* @__PURE__ */ new Set();
38130
+ for (const fn of facts.v2.rustFile.functions) {
38131
+ if (fn.inTestConfig && fn.name) testScopes.add(fn.name);
38132
+ }
38133
+ collectMacroIssues(tree.rootNode, testScopes, issues);
38134
+ return issues;
38135
+ }
38136
+ });
38137
+ function collectMacroIssues(node, testScopes, issues) {
38138
+ if (node.type === "macro_invocation") {
38139
+ const text = node.text;
38140
+ const m = text.match(/^([A-Za-z_][A-Za-z0-9_]*)/);
38141
+ const macroName = m?.[1] ?? "";
38142
+ if (TODO_MACROS.has(macroName)) {
38143
+ if (!isInsideMacroDefinition(node) && !isInsideTestFunction(node, testScopes)) {
38144
+ issues.push({
38145
+ ruleId: "rust/todo-macro",
38146
+ category: "logic",
38147
+ severity: "medium",
38148
+ aiSpecific: true,
38149
+ message: `'${macroName}!()' in production code \u2014 both expand to panic!()`,
38150
+ line: node.startPosition.row + 1,
38151
+ column: node.startPosition.column,
38152
+ 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.`
38153
+ });
38154
+ }
38155
+ }
38156
+ }
38157
+ for (let i = 0; i < node.namedChildCount; i++) {
38158
+ const child = node.namedChild(i);
38159
+ if (child) collectMacroIssues(child, testScopes, issues);
38160
+ }
38161
+ }
38162
+ function isInsideMacroDefinition(node) {
38163
+ for (let p = node.parent; p; p = p.parent) {
38164
+ if (p.type === "macro_definition") return true;
38165
+ if (p.type === "source_file") return false;
38166
+ }
38167
+ return false;
38168
+ }
38169
+ function isInsideTestFunction(node, testScopes) {
38170
+ for (let p = node.parent; p; p = p.parent) {
38171
+ if (p.type === "function_item") {
38172
+ const nameField = p.childForFieldName("name");
38173
+ const name = nameField?.text;
38174
+ if (name && testScopes.has(name)) return true;
38175
+ if (p.text.startsWith("#[test]") || p.text.startsWith("#[cfg(test)]")) return true;
38176
+ return false;
38177
+ }
38178
+ if (p.type === "source_file") return false;
38179
+ }
38180
+ return false;
38181
+ }
38182
+
38183
+ // src/rules/rust/unused-pub-fn.ts
38184
+ var API_CONVENTION_NAMES = /* @__PURE__ */ new Set([
38185
+ "new",
38186
+ "default",
38187
+ "from",
38188
+ "from_str",
38189
+ "from_iter",
38190
+ "try_from",
38191
+ "into",
38192
+ "into_iter",
38193
+ "try_into",
38194
+ "as_ref",
38195
+ "as_mut",
38196
+ "clone",
38197
+ "fmt",
38198
+ "eq",
38199
+ "hash",
38200
+ "partial_cmp",
38201
+ "cmp",
38202
+ "ord",
38203
+ "partial_eq"
38204
+ ]);
38205
+ var rustUnusedPubFnRule = createRule({
38206
+ id: "rust/unused-pub-fn",
38207
+ category: "logic",
38208
+ severity: "low",
38209
+ aiSpecific: true,
38210
+ description: "Public function in a Rust file that has no in-file references",
38211
+ create(_context) {
38212
+ return {};
38213
+ },
38214
+ analyze(_context, facts) {
38215
+ const issues = [];
38216
+ if (!facts.v2?.rustFile) return issues;
38217
+ const rust = facts.v2.rustFile;
38218
+ const referenced = collectReferencedNames(facts.v2._source ?? "");
38219
+ for (const fn of rust.functions) {
38220
+ if (!fn.isPublic) continue;
38221
+ if (API_CONVENTION_NAMES.has(fn.name)) continue;
38222
+ if (fn.inTestConfig) continue;
38223
+ if (referenced.has(fn.name)) continue;
38224
+ issues.push({
38225
+ ruleId: "rust/unused-pub-fn",
38226
+ category: "logic",
38227
+ severity: "low",
38228
+ aiSpecific: true,
38229
+ message: `Public function '${fn.name}' is not referenced anywhere in the file`,
38230
+ line: fn.line,
38231
+ column: fn.column,
38232
+ 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.`
38233
+ });
38234
+ }
38235
+ return issues;
38236
+ }
38237
+ });
38238
+ function collectReferencedNames(source) {
38239
+ const out = /* @__PURE__ */ new Set();
38240
+ for (const m of source.matchAll(/\b([A-Za-z_][A-Za-z0-9_]*)\b/g)) {
38241
+ out.add(m[1]);
38242
+ }
38243
+ return out;
38244
+ }
38245
+
38246
+ // src/rules/rust/unwrap-in-production.ts
38247
+ init_parser_rust();
38248
+ var UNWRAP_METHODS = /* @__PURE__ */ new Set(["unwrap", "expect", "unwrap_or_else"]);
38249
+ var rustUnwrapInProductionRule = createRule({
38250
+ id: "rust/unwrap-in-production",
38251
+ category: "logic",
38252
+ severity: "medium",
38253
+ aiSpecific: true,
38254
+ description: ".unwrap() / .expect() called outside of #[cfg(test)] / #[test] scope",
38255
+ create(_context) {
38256
+ return {};
38257
+ },
38258
+ analyze(_context, facts) {
38259
+ const issues = [];
38260
+ if (!facts.v2?.rustFile) return issues;
38261
+ const source = facts.v2._source ?? "";
38262
+ if (!source) return issues;
38263
+ const tree = parseRust(source);
38264
+ if (!tree) return issues;
38265
+ const testScopes = /* @__PURE__ */ new Set();
38266
+ for (const fn of facts.v2.rustFile.functions) {
38267
+ if (fn.inTestConfig && fn.name) testScopes.add(fn.name);
38268
+ }
38269
+ collectUnwrapIssues(tree.rootNode, testScopes, issues);
38270
+ return issues;
38271
+ }
38272
+ });
38273
+ function collectUnwrapIssues(node, testScopes, issues) {
38274
+ if (node.type === "call_expression") {
38275
+ const fn = node.childForFieldName("function");
38276
+ if (fn && fn.type === "field_expression") {
38277
+ const field = fn.childForFieldName("field");
38278
+ if (field && field.type === "field_identifier" && UNWRAP_METHODS.has(field.text)) {
38279
+ if (!isInsideTestFunction2(node, testScopes)) {
38280
+ issues.push({
38281
+ ruleId: "rust/unwrap-in-production",
38282
+ category: "logic",
38283
+ severity: "medium",
38284
+ aiSpecific: true,
38285
+ message: `'.${field.text}()' called in production code \u2014 panic risk on Err/None`,
38286
+ line: node.startPosition.row + 1,
38287
+ column: node.startPosition.column,
38288
+ 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.`
38289
+ });
38290
+ }
38291
+ }
38292
+ }
38293
+ }
38294
+ for (let i = 0; i < node.namedChildCount; i++) {
38295
+ const child = node.namedChild(i);
38296
+ if (child) collectUnwrapIssues(child, testScopes, issues);
38297
+ }
38298
+ }
38299
+ function isInsideTestFunction2(node, testScopes) {
38300
+ for (let p = node.parent; p; p = p.parent) {
38301
+ if (p.type === "function_item") {
38302
+ const nameField = p.childForFieldName("name");
38303
+ const name = nameField?.text;
38304
+ if (name && testScopes.has(name)) return true;
38305
+ if (p.text.startsWith("#[test]") || p.text.startsWith("#[cfg(test)]")) return true;
38306
+ return false;
38307
+ }
38308
+ if (p.type === "source_file") return false;
38309
+ }
38310
+ return false;
38311
+ }
38312
+
36945
38313
  // src/rules/security/dangerous-cors.ts
36946
38314
  var HEADER_LITERAL_RE = /['"]Access-Control-Allow-Origin['"]\s*[,:=]\s*['"]\*['"]/g;
36947
38315
  var CORS_BLOCK_RE = /\bcors\s*\(\s*\{([^}]*)\}\s*\)/g;
@@ -39973,6 +41341,10 @@ var builtinRules = [
39973
41341
  halsteadAnomalyRule,
39974
41342
  terminologyDriftRule,
39975
41343
  uxPatternFragmentationRule,
41344
+ rustStringlyTypedRule,
41345
+ rustTodoMacroRule,
41346
+ rustUnusedPubFnRule,
41347
+ rustUnwrapInProductionRule,
39976
41348
  dangerousCorsRule,
39977
41349
  evalRule,
39978
41350
  exposedEnvVarRule,
@@ -40047,6 +41419,22 @@ var RuleRegistry = class {
40047
41419
  if (!filter) return list;
40048
41420
  return list.filter((r) => filter.kind === "ai" ? r.aiSpecific : !r.aiSpecific);
40049
41421
  }
41422
+ /** v0.18.8: remove every rule where `predicate(rule)` returns true.
41423
+ * Used by focused calibration scripts to scan a single category
41424
+ * without instantiating all 99 rules. */
41425
+ removeWhere(predicate) {
41426
+ let removed = 0;
41427
+ for (const [id, rule] of this.rules) {
41428
+ if (predicate(rule)) {
41429
+ this.rules.delete(id);
41430
+ removed++;
41431
+ }
41432
+ }
41433
+ return removed;
41434
+ }
41435
+ all() {
41436
+ return Array.from(this.rules.values());
41437
+ }
40050
41438
  createContexts(config, filePath, cwd, hotspotIssues = []) {
40051
41439
  const context = {
40052
41440
  config,
@@ -40067,1044 +41455,1793 @@ var RuleRegistry = class {
40067
41455
 
40068
41456
  // src/rules/signal-strength.json
40069
41457
  var signal_strength_default = {
40070
- "logic/math-console-log-storm": {
40071
- recall: 7e-3,
40072
- fpRate: 1e-3,
40073
- ratio: 6.71,
40074
- precision: 0.8968,
40075
- lastCalibratedAt: "2026-06-27T12:00:00Z",
41458
+ "ai/any-density": {
41459
+ recall: 6e-3,
41460
+ fpRate: 37e-4,
41461
+ ratio: 175.31,
41462
+ precision: 0.6523,
41463
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
40076
41464
  verdict: "USEFUL",
40077
- _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.",
40078
- aiSpecific: true
41465
+ _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).",
41466
+ aiSpecific: true,
41467
+ _v7Verdict: "USEFUL",
41468
+ _v7Lift: 153.41,
41469
+ _v7Recall: 55e-4,
41470
+ _v7FpRate: 41e-4,
41471
+ _v7Precision: 0.634,
41472
+ _v8Verdict: "USEFUL",
41473
+ _v8Lift: 271.97
40079
41474
  },
40080
- "logic/math-any-density": {
40081
- recall: 16e-4,
40082
- fpRate: 13e-4,
40083
- ratio: 1.17,
40084
- precision: 0.6035,
40085
- lastCalibratedAt: "2026-06-27T12:00:00Z",
40086
- verdict: "NOISY",
40087
- _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.",
40088
- defaultOff: true,
40089
- aiSpecific: true
41475
+ "ai/comment-ratio": {
41476
+ recall: 0.2771,
41477
+ fpRate: 0.1578,
41478
+ ratio: 4.26,
41479
+ precision: 0.6721,
41480
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
41481
+ verdict: "USEFUL",
41482
+ _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).",
41483
+ aiSpecific: true,
41484
+ _v7Verdict: "USEFUL",
41485
+ _v7Lift: 4.11,
41486
+ _v7Recall: 0.2545,
41487
+ _v7FpRate: 0.1629,
41488
+ _v7Precision: 0.6687,
41489
+ _v8Verdict: "USEFUL",
41490
+ _v8Lift: 4.73
40090
41491
  },
40091
- "logic/boundary-violation": {
40092
- recall: 0.0263,
40093
- fpRate: 0.0175,
40094
- ratio: 1.5,
40095
- precision: 0.6601,
40096
- lastCalibratedAt: "2026-06-27T12:00:00Z",
40097
- verdict: "HYGIENE",
40098
- _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.",
40099
- aiSpecific: false
41492
+ "ai/compression-profile": {
41493
+ recall: 0.3478,
41494
+ fpRate: 0.1488,
41495
+ ratio: 4.92,
41496
+ precision: 0.7318,
41497
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
41498
+ verdict: "USEFUL",
41499
+ _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).",
41500
+ aiSpecific: true,
41501
+ _v7Verdict: "USEFUL",
41502
+ _v7Lift: 4.89,
41503
+ _v7Recall: 0.3166,
41504
+ _v7FpRate: 0.1498,
41505
+ _v7Precision: 0.732,
41506
+ _v8Verdict: "USEFUL",
41507
+ _v8Lift: 5
40100
41508
  },
40101
- "logic/reactive-hook-soup": {
40102
- recall: 38e-4,
41509
+ "ai/console-debug-storm": {
41510
+ recall: 73e-4,
40103
41511
  fpRate: 9e-4,
40104
- ratio: 4.29,
40105
- precision: 0.8476,
40106
- lastCalibratedAt: "2026-06-27T12:00:00Z",
41512
+ ratio: 949.21,
41513
+ precision: 0.9,
41514
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
40107
41515
  verdict: "USEFUL",
40108
- _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.",
40109
- aiSpecific: true
41516
+ _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).",
41517
+ aiSpecific: true,
41518
+ _v7Verdict: "USEFUL",
41519
+ _v7Lift: 960.19,
41520
+ _v7Recall: 81e-4,
41521
+ _v7FpRate: 1e-3,
41522
+ _v7Precision: 0.9161,
41523
+ _v8Verdict: "USEFUL",
41524
+ _v8Lift: 845.55
40110
41525
  },
40111
- "logic/optimistic-no-rollback": {
40112
- recall: 12e-4,
40113
- fpRate: 3e-4,
40114
- ratio: 3.61,
40115
- precision: 0.824,
40116
- lastCalibratedAt: "2026-06-27T12:00:00Z",
41526
+ "ai/default-react-stack": {
41527
+ recall: 1e-3,
41528
+ fpRate: 0,
41529
+ ratio: 251225.49,
41530
+ precision: 0.9966,
41531
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
40117
41532
  verdict: "USEFUL",
40118
- _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.",
40119
- aiSpecific: true
41533
+ _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).",
41534
+ aiSpecific: true,
41535
+ _v7Verdict: "USEFUL",
41536
+ _v7Lift: 182622.43,
41537
+ _v7Recall: 1e-3,
41538
+ _v7FpRate: 0,
41539
+ _v7Precision: 0.9957,
41540
+ _v8Verdict: "USEFUL",
41541
+ _v8Lift: 99999
40120
41542
  },
40121
- "logic/zombie-state": {
40122
- recall: 1e-4,
40123
- fpRate: 0,
40124
- ratio: 9.26,
40125
- precision: 0.9231,
40126
- lastCalibratedAt: "2026-06-27T12:00:00Z",
41543
+ "ai/errors-near-eof": {
41544
+ recall: 0.0948,
41545
+ fpRate: 0.052,
41546
+ ratio: 13.09,
41547
+ precision: 0.6803,
41548
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
40127
41549
  verdict: "USEFUL",
40128
- _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.",
40129
- aiSpecific: true
41550
+ _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).",
41551
+ aiSpecific: true,
41552
+ _v7Verdict: "USEFUL",
41553
+ _v7Lift: 11.29,
41554
+ _v7Recall: 0.0704,
41555
+ _v7FpRate: 0.0551,
41556
+ _v7Precision: 0.6225,
41557
+ _v8Verdict: "USEFUL",
41558
+ _v8Lift: 18.16
40130
41559
  },
40131
- "logic/math-gini-class-usage": {
40132
- recall: 13e-4,
41560
+ "ai/fetch-default-overuse": {
41561
+ recall: 27e-4,
40133
41562
  fpRate: 3e-4,
40134
- ratio: 5.09,
40135
- precision: 0.8683,
40136
- lastCalibratedAt: "2026-06-27T12:00:00Z",
41563
+ ratio: 2679.84,
41564
+ precision: 0.9036,
41565
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
40137
41566
  verdict: "USEFUL",
40138
- _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.",
40139
- aiSpecific: true
41567
+ _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).",
41568
+ aiSpecific: true,
41569
+ _v7Verdict: "USEFUL",
41570
+ _v7Lift: 2166.14,
41571
+ _v7Recall: 28e-4,
41572
+ _v7FpRate: 4e-4,
41573
+ _v7Precision: 0.8976,
41574
+ _v8Verdict: "USEFUL",
41575
+ _v8Lift: 7139.19
40140
41576
  },
40141
- "visual/math-color-cluster": {
40142
- recall: 2e-4,
41577
+ "ai/library-reinvention": {
41578
+ recall: 3e-4,
40143
41579
  fpRate: 0,
40144
- ratio: 8.95,
40145
- precision: 0.9206,
40146
- lastCalibratedAt: "2026-06-27T12:00:00Z",
40147
- verdict: "USEFUL",
40148
- _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.",
40149
- aiSpecific: true
40150
- },
40151
- "visual/math-default-font": {
40152
- recall: 13e-4,
40153
- fpRate: 4e-4,
40154
- ratio: 3.4,
40155
- precision: 0.8151,
40156
- lastCalibratedAt: "2026-06-27T12:00:00Z",
41580
+ ratio: 47415.05,
41581
+ precision: 0.9405,
41582
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
40157
41583
  verdict: "USEFUL",
40158
- _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.",
40159
- aiSpecific: true
41584
+ _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).",
41585
+ aiSpecific: true,
41586
+ _v7Verdict: "USEFUL",
41587
+ _v7Lift: 34024.44,
41588
+ _v7Recall: 3e-4,
41589
+ _v7FpRate: 0,
41590
+ _v7Precision: 0.9275,
41591
+ _v8Verdict: "USEFUL",
41592
+ _v8Lift: 99999
40160
41593
  },
40161
- "visual/math-gradient-hue-rotation": {
41594
+ "ai/log-rank-histogram": {
40162
41595
  recall: 0,
40163
41596
  fpRate: 0,
40164
41597
  ratio: 0,
40165
41598
  precision: 0,
40166
- lastCalibratedAt: "2026-06-25T00:00:00Z",
41599
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
40167
41600
  verdict: "DORMANT",
40168
- defaultOff: true,
40169
- _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.)",
40170
- aiSpecific: true
40171
- },
40172
- "visual/math-rounded-entropy": {
40173
- recall: 37e-4,
40174
- fpRate: 3e-4,
40175
- ratio: 10.9,
40176
- precision: 0.9339,
40177
- lastCalibratedAt: "2026-06-27T12:00:00Z",
40178
- verdict: "USEFUL",
40179
- _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.",
40180
- aiSpecific: true
40181
- },
40182
- "visual/math-font-entropy": {
40183
- recall: 45e-4,
40184
- fpRate: 13e-4,
40185
- ratio: 3.32,
40186
- precision: 0.8114,
40187
- lastCalibratedAt: "2026-06-27T12:00:00Z",
40188
- verdict: "USEFUL",
40189
- _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.",
40190
- aiSpecific: true
41601
+ _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.",
41602
+ aiSpecific: true,
41603
+ _v7Verdict: "OK",
41604
+ _v7Lift: 0,
41605
+ _v7Recall: 0,
41606
+ _v7FpRate: 0,
41607
+ _v7Precision: 0,
41608
+ _v8Verdict: "DORMANT",
41609
+ _v8Lift: 1,
41610
+ defaultOff: true
40191
41611
  },
40192
- "visual/math-spacing-entropy": {
40193
- recall: 18e-4,
40194
- fpRate: 6e-4,
40195
- ratio: 3.01,
40196
- precision: 0.7959,
40197
- lastCalibratedAt: "2026-06-27T12:00:00Z",
40198
- verdict: "USEFUL",
40199
- _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.",
40200
- aiSpecific: true
41612
+ "ai/markdown-leakage": {
41613
+ recall: 0,
41614
+ fpRate: 0,
41615
+ ratio: 10003.17,
41616
+ precision: 0.3571,
41617
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
41618
+ verdict: "OK",
41619
+ _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).",
41620
+ aiSpecific: true,
41621
+ _v7Verdict: "USEFUL",
41622
+ _v7Lift: 65504.64,
41623
+ _v7Recall: 0,
41624
+ _v7FpRate: 0,
41625
+ _v7Precision: 0.7143,
41626
+ _v8Verdict: "INVERTED",
41627
+ _v8Lift: 0
40201
41628
  },
40202
- "visual/clamp-soup": {
41629
+ "ai/renyi-profile": {
40203
41630
  recall: 0,
40204
41631
  fpRate: 0,
40205
- ratio: 0,
40206
- precision: 0,
40207
- lastCalibratedAt: "2026-06-25T00:00:00Z",
40208
- verdict: "DORMANT",
40209
- defaultOff: true,
40210
- _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.)",
40211
- aiSpecific: true
41632
+ ratio: 5251.67,
41633
+ precision: 0.25,
41634
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
41635
+ verdict: "OK",
41636
+ _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).",
41637
+ aiSpecific: true,
41638
+ _v7Verdict: "OK",
41639
+ _v7Lift: 5094.81,
41640
+ _v7Recall: 0,
41641
+ _v7FpRate: 0,
41642
+ _v7Precision: 0.25,
41643
+ _v8Verdict: "OK",
41644
+ _v8Lift: 5722.25
40212
41645
  },
40213
- "component/giant-component": {
40214
- recall: 0.0176,
40215
- fpRate: 77e-4,
40216
- ratio: 2.3,
40217
- precision: 0.7485,
40218
- lastCalibratedAt: "2026-06-27T12:00:00Z",
41646
+ "ai/segment-surprisal-cv": {
41647
+ recall: 0.2019,
41648
+ fpRate: 0.0787,
41649
+ ratio: 9.52,
41650
+ precision: 0.7495,
41651
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
40219
41652
  verdict: "USEFUL",
40220
- _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.",
40221
- aiSpecific: true
41653
+ _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).",
41654
+ aiSpecific: true,
41655
+ _v7Verdict: "USEFUL",
41656
+ _v7Lift: 9.11,
41657
+ _v7Recall: 0.1836,
41658
+ _v7FpRate: 0.0817,
41659
+ _v7Precision: 0.7438,
41660
+ _v8Verdict: "USEFUL",
41661
+ _v8Lift: 10.8
40222
41662
  },
40223
- "component/shadcn-prop-mismatch": {
40224
- recall: 13e-4,
40225
- fpRate: 1e-4,
40226
- ratio: 10.1,
40227
- precision: 0.929,
40228
- lastCalibratedAt: "2026-06-27T12:00:00Z",
41663
+ "ai/state-default-overuse": {
41664
+ recall: 3e-3,
41665
+ fpRate: 6e-4,
41666
+ ratio: 1315.06,
41667
+ precision: 0.8451,
41668
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
40229
41669
  verdict: "USEFUL",
40230
- _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.",
40231
- aiSpecific: true
41670
+ _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).",
41671
+ aiSpecific: true,
41672
+ _v7Verdict: "USEFUL",
41673
+ _v7Lift: 947.32,
41674
+ _v7Recall: 3e-3,
41675
+ _v7FpRate: 9e-4,
41676
+ _v7Precision: 0.8161,
41677
+ _v8Verdict: "USEFUL",
41678
+ _v8Lift: 16799.55
40232
41679
  },
40233
- "layout/math-grid-uniformity": {
40234
- recall: 3e-4,
40235
- fpRate: 2e-4,
40236
- ratio: 1.72,
40237
- precision: 0.6907,
40238
- lastCalibratedAt: "2026-06-27T12:00:00Z",
40239
- verdict: "OK",
40240
- _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.",
40241
- aiSpecific: true
40242
- },
40243
- "layout/math-element-uniformity": {
40244
- recall: 28e-4,
40245
- fpRate: 12e-4,
40246
- ratio: 2.28,
40247
- precision: 0.7475,
40248
- lastCalibratedAt: "2026-06-27T12:00:00Z",
41680
+ "ai/tailwind-color-overuse": {
41681
+ recall: 0.0264,
41682
+ fpRate: 38e-4,
41683
+ ratio: 230.97,
41684
+ precision: 0.8888,
41685
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
40249
41686
  verdict: "USEFUL",
40250
- _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.",
40251
- aiSpecific: true
40252
- },
40253
- "typo/math-button-label-uniformity": {
40254
- recall: 2e-4,
40255
- fpRate: 1e-4,
40256
- ratio: 1.36,
40257
- precision: 0.6379,
40258
- lastCalibratedAt: "2026-06-27T12:00:00Z",
40259
- verdict: "HYGIENE",
40260
- _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.",
40261
- aiSpecific: false
41687
+ _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).",
41688
+ aiSpecific: true,
41689
+ _v7Verdict: "USEFUL",
41690
+ _v7Lift: 161.52,
41691
+ _v7Recall: 0.0218,
41692
+ _v7FpRate: 52e-4,
41693
+ _v7Precision: 0.8436,
41694
+ _v8Verdict: "USEFUL",
41695
+ _v8Lift: 5695.79
40262
41696
  },
40263
- "perf/css-bloat": {
40264
- recall: 0.0117,
40265
- fpRate: 32e-4,
40266
- ratio: 3.64,
40267
- precision: 0.8252,
40268
- lastCalibratedAt: "2026-06-27T12:00:00Z",
40269
- verdict: "HYGIENE",
40270
- _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.",
40271
- aiSpecific: false
41697
+ "ai/text-like-ratio": {
41698
+ recall: 0,
41699
+ fpRate: 0,
41700
+ ratio: 201664,
41701
+ precision: 0.8,
41702
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
41703
+ verdict: "USEFUL",
41704
+ _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).",
41705
+ aiSpecific: true,
41706
+ _v7Verdict: "USEFUL",
41707
+ _v7Lift: 137559.75,
41708
+ _v7Recall: 0,
41709
+ _v7FpRate: 0,
41710
+ _v7Precision: 0.75,
41711
+ _v8Verdict: "USEFUL",
41712
+ _v8Lift: 99999
40272
41713
  },
40273
- "wcag/focus-appearance": {
40274
- recall: 26e-4,
40275
- fpRate: 1e-4,
40276
- ratio: 19.68,
40277
- precision: 0.9623,
40278
- lastCalibratedAt: "2026-06-27T12:00:00Z",
40279
- verdict: "HYGIENE",
40280
- _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.",
40281
- aiSpecific: false
41714
+ "ai/whitespace-regularity": {
41715
+ recall: 0.0733,
41716
+ fpRate: 0.0677,
41717
+ ratio: 8.25,
41718
+ precision: 0.5583,
41719
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
41720
+ verdict: "USEFUL",
41721
+ _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).",
41722
+ aiSpecific: true,
41723
+ _v7Verdict: "USEFUL",
41724
+ _v7Lift: 7.71,
41725
+ _v7Recall: 0.0737,
41726
+ _v7FpRate: 0.0733,
41727
+ _v7Precision: 0.5652,
41728
+ _v8Verdict: "USEFUL",
41729
+ _v8Lift: 10.06
40282
41730
  },
40283
- "wcag/target-size": {
41731
+ "arch/astro-island-leak": {
40284
41732
  recall: 0,
40285
41733
  fpRate: 0,
40286
41734
  ratio: 0,
40287
41735
  precision: 0,
40288
- lastCalibratedAt: "2026-06-25T00:00:00Z",
41736
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
40289
41737
  verdict: "DORMANT",
40290
- defaultOff: true,
40291
- _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.)",
40292
- aiSpecific: false
40293
- },
40294
- "component/multiple-components-per-file": {
40295
- recall: 0.0681,
40296
- fpRate: 0.052,
40297
- ratio: 1.31,
40298
- precision: 0.6294,
40299
- lastCalibratedAt: "2026-06-27T12:00:00Z",
40300
- verdict: "HYGIENE",
40301
- _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.",
40302
- aiSpecific: false
41738
+ _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.",
41739
+ aiSpecific: true,
41740
+ _v7Verdict: "DORMANT",
41741
+ _v7Lift: 0,
41742
+ _v7Recall: 0,
41743
+ _v7FpRate: 0,
41744
+ _v7Precision: 0,
41745
+ _v8Verdict: "DORMANT",
41746
+ _v8Lift: 1,
41747
+ defaultOff: true
40303
41748
  },
40304
- "context/import-path-mismatch": {
40305
- recall: 0.0739,
40306
- fpRate: 0.0228,
40307
- ratio: 3.25,
40308
- precision: 0.8079,
40309
- lastCalibratedAt: "2026-06-27T12:00:00Z",
40310
- verdict: "HYGIENE",
40311
- _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.",
40312
- aiSpecific: false
41749
+ "component/giant-component": {
41750
+ recall: 0.0181,
41751
+ fpRate: 59e-4,
41752
+ ratio: 132.31,
41753
+ precision: 0.7815,
41754
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
41755
+ verdict: "USEFUL",
41756
+ _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).",
41757
+ aiSpecific: true,
41758
+ _v7Verdict: "USEFUL",
41759
+ _v7Lift: 97.16,
41760
+ _v7Recall: 0.0177,
41761
+ _v7FpRate: 77e-4,
41762
+ _v7Precision: 0.7485,
41763
+ _v8Verdict: "USEFUL",
41764
+ _v8Lift: 846.15
40313
41765
  },
40314
- "logic/key-prop-missing": {
40315
- recall: 17e-4,
40316
- fpRate: 14e-4,
40317
- ratio: 1.28,
40318
- precision: 0.6246,
40319
- lastCalibratedAt: "2026-06-27T12:00:00Z",
40320
- verdict: "HYGIENE",
40321
- _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.",
40322
- aiSpecific: false
41766
+ "component/multiple-components-per-file": {
41767
+ recall: 0.0751,
41768
+ fpRate: 0.0423,
41769
+ ratio: 15.96,
41770
+ precision: 0.6747,
41771
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
41772
+ verdict: "USEFUL",
41773
+ _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).",
41774
+ aiSpecific: false,
41775
+ _v7Verdict: "USEFUL",
41776
+ _v7Lift: 12.04,
41777
+ _v7Recall: 0.0687,
41778
+ _v7FpRate: 0.0523,
41779
+ _v7Precision: 0.6294,
41780
+ _v8Verdict: "USEFUL",
41781
+ _v8Lift: 54.44
40323
41782
  },
40324
- "logic/math-variable-name-entropy": {
40325
- recall: 2e-4,
41783
+ "component/shadcn-prop-mismatch": {
41784
+ recall: 16e-4,
40326
41785
  fpRate: 1e-4,
40327
- ratio: 1.07,
40328
- precision: 0.5806,
40329
- lastCalibratedAt: "2026-06-27T12:00:00Z",
40330
- verdict: "HYGIENE",
40331
- _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.",
40332
- aiSpecific: false
40333
- },
40334
- "security/public-admin-route": {
40335
- recall: 28e-4,
40336
- fpRate: 78e-4,
40337
- ratio: 0.4,
40338
- precision: 0.2251,
40339
- lastCalibratedAt: "2026-06-26T22:30:00Z",
40340
- verdict: "HYGIENE",
40341
- _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]",
40342
- defaultOff: true,
40343
- aiSpecific: false
40344
- },
40345
- "security/unsafe-html-render": {
40346
- recall: 13e-4,
40347
- fpRate: 9e-4,
40348
- ratio: 1.5,
40349
- precision: 0.661,
40350
- lastCalibratedAt: "2026-06-27T12:00:00Z",
40351
- verdict: "HYGIENE",
40352
- _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.",
40353
- aiSpecific: false
40354
- },
40355
- "visual/naturalness-anomaly": {
40356
- recall: 0.1645,
40357
- fpRate: 0.0617,
40358
- ratio: 2.67,
40359
- precision: 0.7755,
40360
- lastCalibratedAt: "2026-06-27T12:00:00Z",
41786
+ ratio: 9990.98,
41787
+ precision: 0.9512,
41788
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
40361
41789
  verdict: "USEFUL",
40362
- _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.",
40363
- aiSpecific: true
41790
+ _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).",
41791
+ aiSpecific: true,
41792
+ _v7Verdict: "USEFUL",
41793
+ _v7Lift: 7099.57,
41794
+ _v7Recall: 13e-4,
41795
+ _v7FpRate: 1e-4,
41796
+ _v7Precision: 0.929,
41797
+ _v8Verdict: "USEFUL",
41798
+ _v8Lift: 99999
40364
41799
  },
40365
- "perf/halstead-anomaly": {
40366
- recall: 0,
40367
- fpRate: 0,
40368
- ratio: 2.32,
40369
- precision: 0.75,
40370
- lastCalibratedAt: "2026-06-27T12:00:00Z",
41800
+ "context/import-path-mismatch": {
41801
+ recall: 0.0681,
41802
+ fpRate: 0.0167,
41803
+ ratio: 49.48,
41804
+ precision: 0.8263,
41805
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
40371
41806
  verdict: "USEFUL",
40372
- _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.",
40373
- aiSpecific: true
41807
+ _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).",
41808
+ aiSpecific: false,
41809
+ _v7Verdict: "USEFUL",
41810
+ _v7Lift: 35.26,
41811
+ _v7Recall: 0.0746,
41812
+ _v7FpRate: 0.0229,
41813
+ _v7Precision: 0.8079,
41814
+ _v8Verdict: "USEFUL",
41815
+ _v8Lift: 8554.38
40374
41816
  },
40375
- "arch/astro-island-leak": {
41817
+ "db/duplicate-index": {
40376
41818
  recall: 0,
40377
41819
  fpRate: 0,
40378
41820
  ratio: 0,
40379
41821
  precision: 0,
40380
- lastCalibratedAt: "2026-06-25T00:00:00Z",
41822
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
40381
41823
  verdict: "DORMANT",
40382
- defaultOff: true,
40383
- _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.)",
40384
- aiSpecific: true
41824
+ _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.",
41825
+ aiSpecific: false,
41826
+ _v7Verdict: "DORMANT",
41827
+ _v7Lift: 0,
41828
+ _v7Recall: 0,
41829
+ _v7FpRate: 0,
41830
+ _v7Precision: 0,
41831
+ _v8Verdict: "DORMANT",
41832
+ _v8Lift: 1,
41833
+ defaultOff: true
40385
41834
  },
40386
- "logic/qwik-hook-leak": {
41835
+ "db/enum-sprawl": {
40387
41836
  recall: 0,
40388
41837
  fpRate: 0,
40389
41838
  ratio: 0,
40390
41839
  precision: 0,
40391
- lastCalibratedAt: "2026-06-25T00:00:00Z",
41840
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
40392
41841
  verdict: "DORMANT",
40393
- defaultOff: true,
40394
- _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.)",
40395
- aiSpecific: true
41842
+ _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.",
41843
+ aiSpecific: false,
41844
+ _v7Verdict: "DORMANT",
41845
+ _v7Lift: 0,
41846
+ _v7Recall: 0,
41847
+ _v7FpRate: 0,
41848
+ _v7Precision: 0,
41849
+ _v8Verdict: "DORMANT",
41850
+ _v8Lift: 1,
41851
+ defaultOff: true
40396
41852
  },
40397
- "test/missing-edge-case": {
41853
+ "db/missing-fk-index": {
40398
41854
  recall: 0,
40399
41855
  fpRate: 0,
40400
41856
  ratio: 0,
40401
41857
  precision: 0,
40402
- lastCalibratedAt: "2026-06-25T00:00:00Z",
41858
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
40403
41859
  verdict: "DORMANT",
40404
- defaultOff: true,
40405
- _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.)",
40406
- aiSpecific: true
41860
+ _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.",
41861
+ aiSpecific: false,
41862
+ _v7Verdict: "DORMANT",
41863
+ _v7Lift: 0,
41864
+ _v7Recall: 0,
41865
+ _v7FpRate: 0,
41866
+ _v7Precision: 0,
41867
+ _v8Verdict: "DORMANT",
41868
+ _v8Lift: 1,
41869
+ defaultOff: true
40407
41870
  },
40408
- "typo/calc-fontsize": {
41871
+ "db/missing-not-null": {
40409
41872
  recall: 0,
40410
41873
  fpRate: 0,
40411
41874
  ratio: 0,
40412
41875
  precision: 0,
40413
- lastCalibratedAt: "2026-06-25T00:00:00Z",
41876
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
40414
41877
  verdict: "DORMANT",
40415
- defaultOff: true,
40416
- _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).)",
40417
- aiSpecific: false
41878
+ _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.",
41879
+ aiSpecific: false,
41880
+ _v7Verdict: "DORMANT",
41881
+ _v7Lift: 0,
41882
+ _v7Recall: 0,
41883
+ _v7FpRate: 0,
41884
+ _v7Precision: 0,
41885
+ _v8Verdict: "DORMANT",
41886
+ _v8Lift: 1,
41887
+ defaultOff: true
40418
41888
  },
40419
- "typo/clamp-offscale": {
41889
+ "db/naming-inconsistency": {
40420
41890
  recall: 0,
40421
41891
  fpRate: 0,
40422
41892
  ratio: 0,
40423
41893
  precision: 0,
40424
- lastCalibratedAt: "2026-06-25T00:00:00Z",
41894
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
40425
41895
  verdict: "DORMANT",
40426
- defaultOff: true,
40427
- _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.)",
40428
- aiSpecific: false
41896
+ _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.",
41897
+ aiSpecific: false,
41898
+ _v7Verdict: "DORMANT",
41899
+ _v7Lift: 0,
41900
+ _v7Recall: 0,
41901
+ _v7FpRate: 0,
41902
+ _v7Precision: 0,
41903
+ _v8Verdict: "DORMANT",
41904
+ _v8Lift: 1,
41905
+ defaultOff: true
40429
41906
  },
40430
- "typo/math-cta-vocabulary": {
41907
+ "db/sql-concat": {
41908
+ recall: 5e-4,
41909
+ fpRate: 1e-4,
41910
+ ratio: 7511.26,
41911
+ precision: 0.8343,
41912
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
41913
+ verdict: "USEFUL",
41914
+ _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).",
41915
+ aiSpecific: true,
41916
+ _v7Verdict: "DORMANT",
41917
+ _v7Lift: 1,
41918
+ _v7Recall: 0,
41919
+ _v7FpRate: 0,
41920
+ _v7Precision: 0,
41921
+ _v8Verdict: "USEFUL",
41922
+ _v8Lift: 2046.08
41923
+ },
41924
+ "dead/dead-branch": {
41925
+ recall: 2e-4,
41926
+ fpRate: 4e-4,
41927
+ ratio: 1080.68,
41928
+ precision: 0.4244,
41929
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
41930
+ verdict: "OK",
41931
+ _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.",
41932
+ aiSpecific: true,
41933
+ _v7Verdict: "DORMANT",
41934
+ _v7Lift: 1,
41935
+ _v7Recall: 0,
41936
+ _v7FpRate: 0,
41937
+ _v7Precision: 0,
41938
+ _v8Verdict: "OK",
41939
+ _v8Lift: 294.38
41940
+ },
41941
+ "dead/unreachable": {
41942
+ recall: 1e-4,
41943
+ fpRate: 6e-4,
41944
+ ratio: 153.14,
41945
+ precision: 0.0966,
41946
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
41947
+ verdict: "OK",
41948
+ _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.",
41949
+ aiSpecific: true,
41950
+ _v7Verdict: "DORMANT",
41951
+ _v7Lift: 1,
41952
+ _v7Recall: 0,
41953
+ _v7FpRate: 0,
41954
+ _v7Precision: 0,
41955
+ _v8Verdict: "OK",
41956
+ _v8Lift: 41.71
41957
+ },
41958
+ "dead/unused-import": {
41959
+ recall: 0.0379,
41960
+ fpRate: 0.0222,
41961
+ ratio: 30.06,
41962
+ precision: 0.6662,
41963
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
41964
+ verdict: "USEFUL",
41965
+ _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.",
41966
+ aiSpecific: true,
41967
+ _v7Verdict: "DORMANT",
41968
+ _v7Lift: 1,
41969
+ _v7Recall: 0,
41970
+ _v7FpRate: 0,
41971
+ _v7Precision: 0,
41972
+ _v8Verdict: "USEFUL",
41973
+ _v8Lift: 8.19
41974
+ },
41975
+ "dead/unused-local": {
41976
+ recall: 0.0477,
41977
+ fpRate: 74e-4,
41978
+ ratio: 120.18,
41979
+ precision: 0.8834,
41980
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
41981
+ verdict: "USEFUL",
41982
+ _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.",
41983
+ aiSpecific: true,
41984
+ _v7Verdict: "DORMANT",
41985
+ _v7Lift: 1,
41986
+ _v7Recall: 0,
41987
+ _v7FpRate: 0,
41988
+ _v7Precision: 0,
41989
+ _v8Verdict: "USEFUL",
41990
+ _v8Lift: 32.74
41991
+ },
41992
+ "dead/unused-parameter": {
41993
+ recall: 8e-4,
41994
+ fpRate: 27e-4,
41995
+ ratio: 98,
41996
+ precision: 0.2628,
41997
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
41998
+ verdict: "OK",
41999
+ _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.",
42000
+ aiSpecific: true,
42001
+ _v7Verdict: "DORMANT",
42002
+ _v7Lift: 1,
42003
+ _v7Recall: 0,
42004
+ _v7FpRate: 0,
42005
+ _v7Precision: 0,
42006
+ _v8Verdict: "OK",
42007
+ _v8Lift: 26.7
42008
+ },
42009
+ "docs/broken-link": {
42010
+ recall: 14e-4,
42011
+ fpRate: 23e-4,
42012
+ ratio: 178.13,
42013
+ precision: 0.4155,
42014
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
42015
+ verdict: "OK",
42016
+ _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).",
42017
+ aiSpecific: false,
42018
+ _v7Verdict: "DORMANT",
42019
+ _v7Lift: 1,
42020
+ _v7Recall: 0,
42021
+ _v7FpRate: 0,
42022
+ _v7Precision: 0,
42023
+ _v8Verdict: "OK",
42024
+ _v8Lift: 48.52
42025
+ },
42026
+ "docs/expired-code-example": {
40431
42027
  recall: 0,
40432
42028
  fpRate: 0,
40433
42029
  ratio: 0,
40434
42030
  precision: 0,
40435
- lastCalibratedAt: "2026-06-25T00:00:00Z",
40436
- verdict: "DORMANT",
40437
- defaultOff: true,
40438
- _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.)",
40439
- aiSpecific: true
42031
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
42032
+ verdict: "INVERTED",
42033
+ _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).",
42034
+ aiSpecific: false,
42035
+ _v7Verdict: "DORMANT",
42036
+ _v7Lift: 1,
42037
+ _v7Recall: 0,
42038
+ _v7FpRate: 0,
42039
+ _v7Precision: 0,
42040
+ _v8Verdict: "INVERTED",
42041
+ _v8Lift: 0,
42042
+ defaultOff: true
42043
+ },
42044
+ "docs/stale-function-reference": {
42045
+ recall: 26e-4,
42046
+ fpRate: 5e-4,
42047
+ ratio: 1638.47,
42048
+ precision: 0.8515,
42049
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
42050
+ verdict: "USEFUL",
42051
+ _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).",
42052
+ aiSpecific: false,
42053
+ _v7Verdict: "DORMANT",
42054
+ _v7Lift: 1,
42055
+ _v7Recall: 0,
42056
+ _v7FpRate: 0,
42057
+ _v7Precision: 0,
42058
+ _v8Verdict: "USEFUL",
42059
+ _v8Lift: 446.32
42060
+ },
42061
+ "docs/stale-package-reference": {
42062
+ recall: 2e-4,
42063
+ fpRate: 4e-4,
42064
+ ratio: 939.43,
42065
+ precision: 0.3429,
42066
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
42067
+ verdict: "OK",
42068
+ _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).",
42069
+ aiSpecific: false,
42070
+ _v7Verdict: "DORMANT",
42071
+ _v7Lift: 1,
42072
+ _v7Recall: 0,
42073
+ _v7FpRate: 0,
42074
+ _v7Precision: 0,
42075
+ _v8Verdict: "OK",
42076
+ _v8Lift: 255.9
40440
42077
  },
40441
42078
  "layout/forced-layout": {
40442
42079
  recall: 0,
40443
42080
  fpRate: 0,
40444
42081
  ratio: 0,
40445
42082
  precision: 0,
40446
- lastCalibratedAt: "2026-06-25T00:00:00Z",
42083
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
40447
42084
  verdict: "DORMANT",
40448
- defaultOff: true,
40449
- _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.)",
40450
- aiSpecific: true
42085
+ _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.",
42086
+ aiSpecific: true,
42087
+ _v7Verdict: "DORMANT",
42088
+ _v7Lift: 0,
42089
+ _v7Recall: 0,
42090
+ _v7FpRate: 0,
42091
+ _v7Precision: 0,
42092
+ _v8Verdict: "DORMANT",
42093
+ _v8Lift: 1,
42094
+ defaultOff: true
40451
42095
  },
40452
- "visual/generic-centering": {
42096
+ "layout/gap-monopoly": {
42097
+ recall: 3e-4,
42098
+ fpRate: 1e-4,
42099
+ ratio: 8859.33,
42100
+ precision: 0.8083,
42101
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
42102
+ verdict: "USEFUL",
42103
+ _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).",
42104
+ aiSpecific: false,
42105
+ _v7Verdict: "USEFUL",
42106
+ _v7Lift: 6322.11,
42107
+ _v7Recall: 4e-4,
42108
+ _v7FpRate: 1e-4,
42109
+ _v7Precision: 0.7928,
42110
+ _v8Verdict: "USEFUL",
42111
+ _v8Lift: 99999
42112
+ },
42113
+ "layout/math-element-uniformity": {
42114
+ recall: 29e-4,
42115
+ fpRate: 1e-3,
42116
+ ratio: 770.74,
42117
+ precision: 0.7705,
42118
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
42119
+ verdict: "USEFUL",
42120
+ _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).",
42121
+ aiSpecific: true,
42122
+ _v7Verdict: "USEFUL",
42123
+ _v7Lift: 609.32,
42124
+ _v7Recall: 28e-4,
42125
+ _v7FpRate: 12e-4,
42126
+ _v7Precision: 0.7475,
42127
+ _v8Verdict: "USEFUL",
42128
+ _v8Lift: 2211.5
42129
+ },
42130
+ "layout/math-grid-uniformity": {
42131
+ recall: 3e-4,
42132
+ fpRate: 1e-4,
42133
+ ratio: 5839.98,
42134
+ precision: 0.7182,
42135
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
42136
+ verdict: "USEFUL",
42137
+ _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).",
42138
+ aiSpecific: true,
42139
+ _v7Verdict: "USEFUL",
42140
+ _v7Lift: 4222.91,
42141
+ _v7Recall: 3e-4,
42142
+ _v7FpRate: 2e-4,
42143
+ _v7Precision: 0.6907,
42144
+ _v8Verdict: "USEFUL",
42145
+ _v8Lift: 63384.92
42146
+ },
42147
+ "layout/spacing-grid": {
42148
+ recall: 2e-4,
42149
+ fpRate: 2e-4,
42150
+ ratio: 4051.29,
42151
+ precision: 0.6429,
42152
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
42153
+ verdict: "USEFUL",
42154
+ _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).",
42155
+ aiSpecific: false,
42156
+ _v7Verdict: "USEFUL",
42157
+ _v7Lift: 8831,
42158
+ _v7Recall: 2e-4,
42159
+ _v7FpRate: 1e-4,
42160
+ _v7Precision: 0.7222,
42161
+ _v8Verdict: "USEFUL",
42162
+ _v8Lift: 1562.77
42163
+ },
42164
+ "logic/bayesian-conditional": {
40453
42165
  recall: 0,
40454
42166
  fpRate: 0,
40455
42167
  ratio: 0,
40456
42168
  precision: 0,
40457
- lastCalibratedAt: "2026-06-25T00:00:00Z",
42169
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
40458
42170
  verdict: "DORMANT",
40459
- defaultOff: true,
40460
- _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.)",
40461
- aiSpecific: true
42171
+ _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.",
42172
+ aiSpecific: true,
42173
+ _v7Verdict: "DORMANT",
42174
+ _v7Lift: 0,
42175
+ _v7Recall: 0,
42176
+ _v7FpRate: 0,
42177
+ _v7Precision: 0,
42178
+ _v8Verdict: "DORMANT",
42179
+ _v8Lift: 1,
42180
+ defaultOff: true
40462
42181
  },
40463
- "product/terminology-drift": {
40464
- recall: 85e-4,
40465
- fpRate: 28e-4,
40466
- ratio: 3,
40467
- precision: 0.7956,
40468
- lastCalibratedAt: "2026-06-27T12:00:00Z",
40469
- verdict: "HYGIENE",
40470
- _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.",
40471
- aiSpecific: false
42182
+ "logic/boundary-violation": {
42183
+ recall: 0.0274,
42184
+ fpRate: 0.0137,
42185
+ ratio: 51.32,
42186
+ precision: 0.7006,
42187
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
42188
+ verdict: "USEFUL",
42189
+ _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).",
42190
+ aiSpecific: false,
42191
+ _v7Verdict: "USEFUL",
42192
+ _v7Lift: 37.42,
42193
+ _v7Recall: 0.0265,
42194
+ _v7FpRate: 0.0176,
42195
+ _v7Precision: 0.6601,
42196
+ _v8Verdict: "USEFUL",
42197
+ _v8Lift: 298.57
40472
42198
  },
40473
- "product/ux-pattern-fragmentation": {
42199
+ "logic/ghost-defensive": {
40474
42200
  recall: 1e-4,
40475
42201
  fpRate: 0,
40476
- ratio: 3.09,
40477
- precision: 0.8,
40478
- lastCalibratedAt: "2026-06-27T12:00:00Z",
42202
+ ratio: 112035.56,
42203
+ precision: 0.8889,
42204
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
40479
42205
  verdict: "USEFUL",
40480
- _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.",
40481
- aiSpecific: true
42206
+ _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).",
42207
+ aiSpecific: true,
42208
+ _v7Verdict: "USEFUL",
42209
+ _v7Lift: 80917.5,
42210
+ _v7Recall: 1e-4,
42211
+ _v7FpRate: 0,
42212
+ _v7Precision: 0.8824,
42213
+ _v8Verdict: "USEFUL",
42214
+ _v8Lift: 99999
40482
42215
  },
40483
- "security/sql-construction": {
40484
- recall: 3e-3,
40485
- fpRate: 18e-4,
40486
- ratio: 1.63,
40487
- precision: 0.6788,
40488
- lastCalibratedAt: "2026-06-27T12:00:00Z",
42216
+ "logic/heaps-deviation": {
42217
+ recall: 0.0126,
42218
+ fpRate: 0.0178,
42219
+ ratio: 25.54,
42220
+ precision: 0.4536,
42221
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
40489
42222
  verdict: "OK",
40490
- _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.",
40491
- aiSpecific: true
42223
+ _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).",
42224
+ aiSpecific: false,
42225
+ _v7Verdict: "USEFUL",
42226
+ _v7Lift: 41.22,
42227
+ _v7Recall: 0.0123,
42228
+ _v7FpRate: 0.0132,
42229
+ _v7Precision: 0.5461,
42230
+ _v8Verdict: "OK",
42231
+ _v8Lift: 9.36
40492
42232
  },
40493
- "security/missing-auth-check": {
40494
- recall: 63e-4,
40495
- fpRate: 4e-4,
40496
- ratio: 15.3,
40497
- precision: 0.9247,
40498
- lastCalibratedAt: "2026-06-26T22:30:00Z",
42233
+ "logic/key-prop-missing": {
42234
+ recall: 16e-4,
42235
+ fpRate: 11e-4,
42236
+ ratio: 574.52,
42237
+ precision: 0.629,
42238
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
40499
42239
  verdict: "USEFUL",
40500
- _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.",
40501
- aiSpecific: false
42240
+ _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).",
42241
+ aiSpecific: false,
42242
+ _v7Verdict: "USEFUL",
42243
+ _v7Lift: 458.26,
42244
+ _v7Recall: 18e-4,
42245
+ _v7FpRate: 14e-4,
42246
+ _v7Precision: 0.6246,
42247
+ _v8Verdict: "USEFUL",
42248
+ _v8Lift: 1760.69
40502
42249
  },
40503
- "security/dangerous-cors": {
40504
- recall: 5e-4,
40505
- fpRate: 5e-4,
40506
- ratio: 1.05,
40507
- precision: 0.5758,
40508
- lastCalibratedAt: "2026-06-27T12:00:00Z",
42250
+ "logic/ks-distribution-shift": {
42251
+ recall: 0.6889,
42252
+ fpRate: 0.4411,
42253
+ ratio: 1.46,
42254
+ precision: 0.6457,
42255
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
40509
42256
  verdict: "NOISY",
40510
- _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.",
40511
- defaultOff: true,
40512
- aiSpecific: true
40513
- },
40514
- "test/duplicate-setup": {
40515
- recall: 1e-4,
40516
- fpRate: 0,
40517
- ratio: 3.6,
40518
- precision: 0.8235,
40519
- lastCalibratedAt: "2026-06-27T12:00:00Z",
40520
- verdict: "USEFUL",
40521
- _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.",
40522
- aiSpecific: true
40523
- },
40524
- "logic/ghost-defensive": {
40525
- recall: 1e-4,
40526
- fpRate: 0,
40527
- ratio: 5.79,
40528
- precision: 0.8824,
40529
- lastCalibratedAt: "2026-06-27T12:00:00Z",
40530
- verdict: "USEFUL",
40531
- _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.",
40532
- aiSpecific: true
40533
- },
40534
- "typo/calc-raw-px": {
40535
- recall: 0,
40536
- fpRate: 0,
40537
- ratio: 2.32,
40538
- precision: 0.75,
40539
- lastCalibratedAt: "2026-06-27T12:00:00Z",
40540
- verdict: "HYGIENE",
40541
- _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.",
40542
- aiSpecific: false
42257
+ _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).",
42258
+ aiSpecific: false,
42259
+ _v7Verdict: "USEFUL",
42260
+ _v7Lift: 2.09,
42261
+ _v7Recall: 0.6431,
42262
+ _v7FpRate: 0.34,
42263
+ _v7Precision: 0.7096,
42264
+ _v8Verdict: "INVERTED",
42265
+ _v8Lift: 0.71,
42266
+ defaultOff: true
40543
42267
  },
40544
- "security/fail-open-auth": {
40545
- recall: 0,
40546
- fpRate: 0,
40547
- ratio: 99.99,
40548
- precision: 1,
40549
- lastCalibratedAt: "2026-06-27T12:00:00Z",
42268
+ "logic/math-any-density": {
42269
+ recall: 17e-4,
42270
+ fpRate: 13e-4,
42271
+ ratio: 464.59,
42272
+ precision: 0.6027,
42273
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
40550
42274
  verdict: "USEFUL",
40551
- _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.",
40552
- aiSpecific: true
42275
+ _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).",
42276
+ aiSpecific: true,
42277
+ _v7Verdict: "USEFUL",
42278
+ _v7Lift: 448.16,
42279
+ _v7Recall: 16e-4,
42280
+ _v7FpRate: 13e-4,
42281
+ _v7Precision: 0.6035,
42282
+ _v8Verdict: "USEFUL",
42283
+ _v8Lift: 515
40553
42284
  },
40554
- "wcag/focus-obscured": {
40555
- recall: 33e-4,
40556
- fpRate: 9e-4,
40557
- ratio: 3.51,
40558
- precision: 0.82,
40559
- lastCalibratedAt: "2026-06-27T12:00:00Z",
40560
- verdict: "HYGIENE",
40561
- _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.",
40562
- aiSpecific: false
40563
- },
40564
- "visual/arbitrary-escape": {
40565
- recall: 25e-4,
40566
- fpRate: 9e-4,
40567
- ratio: 2.74,
40568
- precision: 0.7802,
40569
- lastCalibratedAt: "2026-06-27T12:00:00Z",
42285
+ "logic/math-console-log-storm": {
42286
+ recall: 65e-4,
42287
+ fpRate: 11e-4,
42288
+ ratio: 794.4,
42289
+ precision: 0.8729,
42290
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
40570
42291
  verdict: "USEFUL",
40571
- _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.",
40572
- aiSpecific: true
42292
+ _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).",
42293
+ aiSpecific: true,
42294
+ _v7Verdict: "USEFUL",
42295
+ _v7Lift: 852.3,
42296
+ _v7Recall: 71e-4,
42297
+ _v7FpRate: 11e-4,
42298
+ _v7Precision: 0.8968,
42299
+ _v8Verdict: "USEFUL",
42300
+ _v8Lift: 595.24
40573
42301
  },
40574
- "security/hardcoded-secret": {
42302
+ "logic/math-gini-class-usage": {
40575
42303
  recall: 13e-4,
40576
- fpRate: 7e-4,
40577
- ratio: 1.72,
40578
- precision: 0.6899,
40579
- lastCalibratedAt: "2026-06-27T12:00:00Z",
40580
- verdict: "OK",
40581
- _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.",
40582
- aiSpecific: true
40583
- },
40584
- "visual/radius-scale-violation": {
40585
- recall: 4e-4,
40586
- fpRate: 0,
40587
- ratio: 24.7,
40588
- precision: 0.9697,
40589
- lastCalibratedAt: "2026-06-27T12:00:00Z",
40590
- verdict: "HYGIENE",
40591
- _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.",
40592
- aiSpecific: false
40593
- },
40594
- "test/fake-placeholder": {
40595
- recall: 53e-4,
40596
- fpRate: 19e-4,
40597
- ratio: 2.82,
40598
- precision: 0.7854,
40599
- lastCalibratedAt: "2026-06-27T12:00:00Z",
42304
+ fpRate: 2e-4,
42305
+ ratio: 4648.6,
42306
+ precision: 0.8852,
42307
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
40600
42308
  verdict: "USEFUL",
40601
- _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.",
40602
- aiSpecific: true
40603
- },
40604
- "security/exposed-env-var": {
40605
- recall: 6e-4,
40606
- fpRate: 7e-4,
40607
- ratio: 0.9,
40608
- precision: 0.5387,
40609
- lastCalibratedAt: "2026-06-27T12:00:00Z",
40610
- verdict: "HYGIENE",
40611
- _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.",
40612
- aiSpecific: false
40613
- },
40614
- "perf/cls-image": {
40615
- recall: 2e-4,
40616
- fpRate: 3e-4,
40617
- ratio: 0.8,
40618
- precision: 0.5104,
40619
- lastCalibratedAt: "2026-06-27T12:00:00Z",
40620
- verdict: "HYGIENE",
40621
- _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.",
40622
- aiSpecific: false
40623
- },
40624
- "layout/gap-monopoly": {
40625
- recall: 4e-4,
40626
- fpRate: 1e-4,
40627
- ratio: 2.95,
40628
- precision: 0.7928,
40629
- lastCalibratedAt: "2026-06-27T12:00:00Z",
40630
- verdict: "HYGIENE",
40631
- _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.",
40632
- aiSpecific: false
40633
- },
40634
- "visual/spacing-scale-violation": {
40635
- recall: 83e-4,
40636
- fpRate: 39e-4,
40637
- ratio: 2.13,
40638
- precision: 0.7342,
40639
- lastCalibratedAt: "2026-06-27T12:00:00Z",
40640
- verdict: "HYGIENE",
40641
- _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.",
40642
- aiSpecific: false
40643
- },
40644
- "visual/inline-style-dominance": {
40645
- recall: 96e-4,
40646
- fpRate: 66e-4,
40647
- ratio: 1.46,
40648
- precision: 0.6535,
40649
- lastCalibratedAt: "2026-06-27T12:00:00Z",
40650
- verdict: "HYGIENE",
40651
- _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.",
40652
- aiSpecific: false
42309
+ _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).",
42310
+ aiSpecific: true,
42311
+ _v7Verdict: "USEFUL",
42312
+ _v7Lift: 3388.64,
42313
+ _v7Recall: 13e-4,
42314
+ _v7FpRate: 3e-4,
42315
+ _v7Precision: 0.8683,
42316
+ _v8Verdict: "USEFUL",
42317
+ _v8Lift: 67541.31
40653
42318
  },
40654
- "layout/spacing-grid": {
42319
+ "logic/math-variable-name-entropy": {
40655
42320
  recall: 2e-4,
40656
42321
  fpRate: 1e-4,
40657
- ratio: 2.01,
40658
- precision: 0.7222,
40659
- lastCalibratedAt: "2026-06-27T12:00:00Z",
40660
- verdict: "HYGIENE",
40661
- _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.",
40662
- aiSpecific: false
40663
- },
40664
- "wcag/dragging-movements": {
40665
- recall: 0,
40666
- fpRate: 0,
40667
- ratio: 0.51,
40668
- precision: 0.4,
40669
- lastCalibratedAt: "2026-06-27T12:00:00Z",
40670
- verdict: "HYGIENE",
40671
- _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.",
40672
- aiSpecific: false
42322
+ ratio: 4548.81,
42323
+ precision: 0.6316,
42324
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
42325
+ verdict: "USEFUL",
42326
+ _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).",
42327
+ aiSpecific: false,
42328
+ _v7Verdict: "USEFUL",
42329
+ _v7Lift: 4096.07,
42330
+ _v7Recall: 2e-4,
42331
+ _v7FpRate: 1e-4,
42332
+ _v7Precision: 0.5806,
42333
+ _v8Verdict: "USEFUL",
42334
+ _v8Lift: 5548.85
40673
42335
  },
40674
- "test/weak-assertion": {
40675
- recall: 0.0414,
40676
- fpRate: 86e-4,
40677
- ratio: 4.83,
40678
- precision: 0.8622,
40679
- lastCalibratedAt: "2026-06-27T12:00:00Z",
42336
+ "logic/optimistic-no-rollback": {
42337
+ recall: 12e-4,
42338
+ fpRate: 2e-4,
42339
+ ratio: 3523.57,
42340
+ precision: 0.8527,
42341
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
40680
42342
  verdict: "USEFUL",
40681
- _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.",
40682
- aiSpecific: true
42343
+ _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).",
42344
+ aiSpecific: true,
42345
+ _v7Verdict: "USEFUL",
42346
+ _v7Lift: 2519.02,
42347
+ _v7Recall: 12e-4,
42348
+ _v7FpRate: 3e-4,
42349
+ _v7Precision: 0.824,
42350
+ _v8Verdict: "USEFUL",
42351
+ _v8Lift: 67726.36
40683
42352
  },
40684
- "logic/bayesian-conditional": {
42353
+ "logic/qwik-hook-leak": {
40685
42354
  recall: 0,
40686
42355
  fpRate: 0,
40687
42356
  ratio: 0,
40688
42357
  precision: 0,
40689
- lastCalibratedAt: "2026-06-27T00:00:00Z",
42358
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
40690
42359
  verdict: "DORMANT",
40691
- defaultOff: true,
40692
- _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.",
40693
- aiSpecific: true
42360
+ _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.",
42361
+ aiSpecific: true,
42362
+ _v7Verdict: "DORMANT",
42363
+ _v7Lift: 0,
42364
+ _v7Recall: 0,
42365
+ _v7FpRate: 0,
42366
+ _v7Precision: 0,
42367
+ _v8Verdict: "DORMANT",
42368
+ _v8Lift: 1,
42369
+ defaultOff: true
40694
42370
  },
40695
- "logic/heaps-deviation": {
40696
- recall: 0.0122,
40697
- fpRate: 0.0132,
40698
- ratio: 0.93,
40699
- precision: 0.5461,
40700
- lastCalibratedAt: "2026-06-27T12:00:00Z",
40701
- verdict: "HYGIENE",
40702
- _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.",
40703
- aiSpecific: false
40704
- },
40705
- "logic/ks-distribution-shift": {
40706
- recall: 0.6375,
40707
- fpRate: 0.338,
40708
- ratio: 1.89,
40709
- precision: 0.7096,
40710
- lastCalibratedAt: "2026-06-27T12:00:00Z",
40711
- verdict: "HYGIENE",
40712
- _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.",
40713
- aiSpecific: false
42371
+ "logic/reactive-hook-soup": {
42372
+ recall: 41e-4,
42373
+ fpRate: 6e-4,
42374
+ ratio: 1370.15,
42375
+ precision: 0.8805,
42376
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
42377
+ verdict: "USEFUL",
42378
+ _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).",
42379
+ aiSpecific: true,
42380
+ _v7Verdict: "USEFUL",
42381
+ _v7Lift: 959.64,
42382
+ _v7Recall: 38e-4,
42383
+ _v7FpRate: 9e-4,
42384
+ _v7Precision: 0.8476,
42385
+ _v8Verdict: "USEFUL",
42386
+ _v8Lift: 99999
40714
42387
  },
40715
42388
  "logic/zipf-slope-anomaly": {
40716
- recall: 0.0156,
40717
- fpRate: 87e-4,
40718
- ratio: 1.79,
40719
- precision: 0.6983,
40720
- lastCalibratedAt: "2026-06-27T12:00:00Z",
40721
- verdict: "HYGIENE",
40722
- _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.",
40723
- aiSpecific: false
42389
+ recall: 0.0168,
42390
+ fpRate: 0.0111,
42391
+ ratio: 57.13,
42392
+ precision: 0.6369,
42393
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
42394
+ verdict: "USEFUL",
42395
+ _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).",
42396
+ aiSpecific: false,
42397
+ _v7Verdict: "USEFUL",
42398
+ _v7Lift: 79.75,
42399
+ _v7Recall: 0.0157,
42400
+ _v7FpRate: 88e-4,
42401
+ _v7Precision: 0.6983,
42402
+ _v8Verdict: "USEFUL",
42403
+ _v8Lift: 28.59
40724
42404
  },
40725
- "ai/markdown-leakage": {
40726
- recall: 0,
42405
+ "logic/zombie-state": {
42406
+ recall: 1e-4,
40727
42407
  fpRate: 0,
40728
- ratio: 1.93,
40729
- precision: 0.7143,
40730
- lastCalibratedAt: "2026-06-27T12:00:00Z",
40731
- verdict: "OK",
40732
- _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.",
40733
- aiSpecific: true
42408
+ ratio: 119891.71,
42409
+ precision: 0.9512,
42410
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
42411
+ verdict: "USEFUL",
42412
+ _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).",
42413
+ aiSpecific: true,
42414
+ _v7Verdict: "USEFUL",
42415
+ _v7Lift: 84652.15,
42416
+ _v7Recall: 1e-4,
42417
+ _v7FpRate: 0,
42418
+ _v7Precision: 0.9231,
42419
+ _v8Verdict: "USEFUL",
42420
+ _v8Lift: 99999
40734
42421
  },
40735
- "ai/comment-ratio": {
40736
- recall: 0.2523,
40737
- fpRate: 0.1619,
40738
- ratio: 1.56,
40739
- precision: 0.6687,
40740
- lastCalibratedAt: "2026-06-27T12:00:00Z",
40741
- verdict: "OK",
40742
- _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.",
40743
- aiSpecific: true
42422
+ "perf/cls-image": {
42423
+ recall: 2e-4,
42424
+ fpRate: 2e-4,
42425
+ ratio: 2895.78,
42426
+ precision: 0.5514,
42427
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
42428
+ verdict: "USEFUL",
42429
+ _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).",
42430
+ aiSpecific: false,
42431
+ _v7Verdict: "USEFUL",
42432
+ _v7Lift: 1991.85,
42433
+ _v7Recall: 2e-4,
42434
+ _v7FpRate: 3e-4,
42435
+ _v7Precision: 0.5104,
42436
+ _v8Verdict: "USEFUL",
42437
+ _v8Lift: 62424.55
40744
42438
  },
40745
- "ai/whitespace-regularity": {
40746
- recall: 0.0731,
40747
- fpRate: 0.0728,
40748
- ratio: 1,
40749
- precision: 0.5652,
40750
- lastCalibratedAt: "2026-06-27T12:00:00Z",
40751
- verdict: "NOISY",
40752
- _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.",
40753
- defaultOff: true,
40754
- aiSpecific: true
42439
+ "perf/css-bloat": {
42440
+ recall: 0.0126,
42441
+ fpRate: 24e-4,
42442
+ ratio: 365.63,
42443
+ precision: 0.8616,
42444
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
42445
+ verdict: "USEFUL",
42446
+ _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).",
42447
+ aiSpecific: false,
42448
+ _v7Verdict: "USEFUL",
42449
+ _v7Lift: 256.1,
42450
+ _v7Recall: 0.0118,
42451
+ _v7FpRate: 32e-4,
42452
+ _v7Precision: 0.8252,
42453
+ _v8Verdict: "USEFUL",
42454
+ _v8Lift: 22813.54
40755
42455
  },
40756
- "ai/text-like-ratio": {
42456
+ "perf/halstead-anomaly": {
40757
42457
  recall: 0,
40758
42458
  fpRate: 0,
40759
- ratio: 2.32,
40760
- precision: 0.75,
40761
- lastCalibratedAt: "2026-06-27T12:00:00Z",
42459
+ ratio: 75624,
42460
+ precision: 0.6,
42461
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
40762
42462
  verdict: "USEFUL",
40763
- _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.",
40764
- aiSpecific: true
42463
+ _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).",
42464
+ aiSpecific: true,
42465
+ _v7Verdict: "USEFUL",
42466
+ _v7Lift: 137559.75,
42467
+ _v7Recall: 0,
42468
+ _v7FpRate: 0,
42469
+ _v7Precision: 0.75,
42470
+ _v8Verdict: "INVERTED",
42471
+ _v8Lift: 0
40765
42472
  },
40766
- "ai/errors-near-eof": {
40767
- recall: 0.0697,
40768
- fpRate: 0.0548,
40769
- ratio: 1.27,
40770
- precision: 0.6225,
40771
- lastCalibratedAt: "2026-06-27T12:00:00Z",
40772
- verdict: "NOISY",
40773
- _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.",
40774
- defaultOff: true,
40775
- aiSpecific: true
42473
+ "product/terminology-drift": {
42474
+ recall: 91e-4,
42475
+ fpRate: 21e-4,
42476
+ ratio: 397.75,
42477
+ precision: 0.8347,
42478
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
42479
+ verdict: "USEFUL",
42480
+ _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).",
42481
+ aiSpecific: false,
42482
+ _v7Verdict: "USEFUL",
42483
+ _v7Lift: 280.09,
42484
+ _v7Recall: 86e-4,
42485
+ _v7FpRate: 28e-4,
42486
+ _v7Precision: 0.7956,
42487
+ _v8Verdict: "USEFUL",
42488
+ _v8Lift: 8477.9
40776
42489
  },
40777
- "ai/any-density": {
40778
- recall: 55e-4,
40779
- fpRate: 41e-4,
40780
- ratio: 1.34,
40781
- precision: 0.634,
40782
- lastCalibratedAt: "2026-06-27T12:00:00Z",
40783
- verdict: "NOISY",
40784
- _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.",
40785
- defaultOff: true,
40786
- aiSpecific: true
42490
+ "product/ux-pattern-fragmentation": {
42491
+ recall: 1e-4,
42492
+ fpRate: 0,
42493
+ ratio: 22864.4,
42494
+ precision: 0.8163,
42495
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
42496
+ verdict: "USEFUL",
42497
+ _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).",
42498
+ aiSpecific: true,
42499
+ _v7Verdict: "USEFUL",
42500
+ _v7Lift: 18341.3,
42501
+ _v7Recall: 1e-4,
42502
+ _v7FpRate: 0,
42503
+ _v7Precision: 0.8,
42504
+ _v8Verdict: "USEFUL",
42505
+ _v8Lift: 61037.33
40787
42506
  },
40788
- "ai/renyi-profile": {
40789
- recall: 0,
42507
+ "rust/stringly-typed": {
42508
+ recall: 2e-4,
40790
42509
  fpRate: 0,
40791
- ratio: 0.26,
40792
- precision: 0.25,
40793
- lastCalibratedAt: "2026-06-27T12:00:00Z",
40794
- verdict: "INVERTED",
40795
- _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.",
40796
- defaultOff: true,
40797
- aiSpecific: true
42510
+ ratio: 24735.12,
42511
+ precision: 0.8831,
42512
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
42513
+ verdict: "USEFUL",
42514
+ _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).",
42515
+ aiSpecific: true,
42516
+ _v7Verdict: "DORMANT",
42517
+ _v7Lift: 1,
42518
+ _v7Recall: 0,
42519
+ _v7FpRate: 0,
42520
+ _v7Precision: 0,
42521
+ _v8Verdict: "USEFUL",
42522
+ _v8Lift: 6737.89
40798
42523
  },
40799
- "ai/log-rank-histogram": {
42524
+ "rust/todo-macro": {
42525
+ recall: 1e-4,
42526
+ fpRate: 7e-4,
42527
+ ratio: 210.08,
42528
+ precision: 0.1392,
42529
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
42530
+ verdict: "OK",
42531
+ _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).",
42532
+ aiSpecific: true,
42533
+ _v7Verdict: "DORMANT",
42534
+ _v7Lift: 1,
42535
+ _v7Recall: 0,
42536
+ _v7FpRate: 0,
42537
+ _v7Precision: 0,
42538
+ _v8Verdict: "OK",
42539
+ _v8Lift: 57.23
42540
+ },
42541
+ "rust/unused-pub-fn": {
40800
42542
  recall: 0,
40801
42543
  fpRate: 0,
40802
- ratio: 0,
40803
- precision: 0,
40804
- lastCalibratedAt: "2026-06-27T00:00:00Z",
42544
+ ratio: 10803.43,
42545
+ precision: 0.3,
42546
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
40805
42547
  verdict: "OK",
40806
- _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).",
40807
- aiSpecific: true
42548
+ _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).",
42549
+ aiSpecific: true,
42550
+ _v7Verdict: "DORMANT",
42551
+ _v7Lift: 1,
42552
+ _v7Recall: 0,
42553
+ _v7FpRate: 0,
42554
+ _v7Precision: 0,
42555
+ _v8Verdict: "OK",
42556
+ _v8Lift: 2942.87
40808
42557
  },
40809
- "ai/segment-surprisal-cv": {
40810
- recall: 0.182,
40811
- fpRate: 0.0812,
40812
- ratio: 2.24,
40813
- precision: 0.7438,
40814
- lastCalibratedAt: "2026-06-27T12:00:00Z",
42558
+ "rust/unwrap-in-production": {
42559
+ recall: 8e-3,
42560
+ fpRate: 77e-4,
42561
+ ratio: 70.81,
42562
+ precision: 0.5475,
42563
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
40815
42564
  verdict: "USEFUL",
40816
- _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.",
40817
- aiSpecific: true
42565
+ _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).",
42566
+ aiSpecific: true,
42567
+ _v7Verdict: "DORMANT",
42568
+ _v7Lift: 1,
42569
+ _v7Recall: 0,
42570
+ _v7FpRate: 0,
42571
+ _v7Precision: 0,
42572
+ _v8Verdict: "USEFUL",
42573
+ _v8Lift: 19.29
40818
42574
  },
40819
- "ai/compression-profile": {
40820
- recall: 0.3139,
40821
- fpRate: 0.1489,
40822
- ratio: 2.11,
40823
- precision: 0.732,
40824
- lastCalibratedAt: "2026-06-27T12:00:00Z",
42575
+ "security/dangerous-cors": {
42576
+ recall: 5e-4,
42577
+ fpRate: 4e-4,
42578
+ ratio: 1721.87,
42579
+ precision: 0.6079,
42580
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
40825
42581
  verdict: "USEFUL",
40826
- _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.",
40827
- aiSpecific: true
42582
+ _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).",
42583
+ aiSpecific: true,
42584
+ _v7Verdict: "USEFUL",
42585
+ _v7Lift: 1257.16,
42586
+ _v7Recall: 5e-4,
42587
+ _v7FpRate: 5e-4,
42588
+ _v7Precision: 0.5758,
42589
+ _v8Verdict: "USEFUL",
42590
+ _v8Lift: 11365.57
40828
42591
  },
40829
- "ai/tailwind-color-overuse": {
40830
- recall: 0.0216,
40831
- fpRate: 52e-4,
40832
- ratio: 4.16,
40833
- precision: 0.8436,
40834
- lastCalibratedAt: "2026-06-27T12:00:00Z",
42592
+ "security/eval": {
42593
+ recall: 1e-4,
42594
+ fpRate: 2e-4,
42595
+ ratio: 1929.18,
42596
+ precision: 0.4286,
42597
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
42598
+ verdict: "OK",
42599
+ _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).",
42600
+ aiSpecific: false,
42601
+ _v7Verdict: "DORMANT",
42602
+ _v7Lift: 1,
42603
+ _v7Recall: 0,
42604
+ _v7FpRate: 0,
42605
+ _v7Precision: 0,
42606
+ _v8Verdict: "OK",
42607
+ _v8Lift: 525.51
42608
+ },
42609
+ "security/exposed-env-var": {
42610
+ recall: 6e-4,
42611
+ fpRate: 5e-4,
42612
+ ratio: 1055.81,
42613
+ precision: 0.5696,
42614
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
40835
42615
  verdict: "USEFUL",
40836
- _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.",
40837
- aiSpecific: true
42616
+ _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).",
42617
+ aiSpecific: false,
42618
+ _v7Verdict: "USEFUL",
42619
+ _v7Lift: 790.5,
42620
+ _v7Recall: 6e-4,
42621
+ _v7FpRate: 7e-4,
42622
+ _v7Precision: 0.5387,
42623
+ _v8Verdict: "USEFUL",
42624
+ _v8Lift: 4716.52
40838
42625
  },
40839
- "ai/default-react-stack": {
40840
- recall: 1e-3,
42626
+ "security/fail-open-auth": {
42627
+ recall: 0,
40841
42628
  fpRate: 0,
40842
- ratio: 99.99,
40843
- precision: 0.9957,
40844
- lastCalibratedAt: "2026-06-27T12:00:00Z",
42629
+ ratio: 99999,
42630
+ precision: 1,
42631
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
40845
42632
  verdict: "USEFUL",
40846
- _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.",
40847
- aiSpecific: true
42633
+ _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).",
42634
+ aiSpecific: true,
42635
+ _v7Verdict: "USEFUL",
42636
+ _v7Lift: 99999,
42637
+ _v7Recall: 0,
42638
+ _v7FpRate: 0,
42639
+ _v7Precision: 1,
42640
+ _v8Verdict: "DORMANT",
42641
+ _v8Lift: 1
40848
42642
  },
40849
- "ai/library-reinvention": {
40850
- recall: 3e-4,
42643
+ "security/hardcoded-secret": {
42644
+ recall: 14e-4,
42645
+ fpRate: 6e-4,
42646
+ ratio: 1269.08,
42647
+ precision: 0.735,
42648
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
42649
+ verdict: "USEFUL",
42650
+ _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).",
42651
+ aiSpecific: true,
42652
+ _v7Verdict: "USEFUL",
42653
+ _v7Lift: 916.92,
42654
+ _v7Recall: 13e-4,
42655
+ _v7FpRate: 8e-4,
42656
+ _v7Precision: 0.6899,
42657
+ _v8Verdict: "USEFUL",
42658
+ _v8Lift: 7935.57
42659
+ },
42660
+ "security/localstorage-token": {
42661
+ recall: 1e-4,
40851
42662
  fpRate: 0,
40852
- ratio: 9.88,
40853
- precision: 0.9275,
40854
- lastCalibratedAt: "2026-06-27T12:00:00Z",
42663
+ ratio: 99999,
42664
+ precision: 1,
42665
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
40855
42666
  verdict: "USEFUL",
40856
- _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.",
40857
- aiSpecific: true
42667
+ _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).",
42668
+ aiSpecific: false,
42669
+ _v7Verdict: "DORMANT",
42670
+ _v7Lift: 1,
42671
+ _v7Recall: 0,
42672
+ _v7FpRate: 0,
42673
+ _v7Precision: 0,
42674
+ _v8Verdict: "USEFUL",
42675
+ _v8Lift: 99999
40858
42676
  },
40859
- "ai/state-default-overuse": {
40860
- recall: 29e-4,
40861
- fpRate: 9e-4,
40862
- ratio: 3.42,
40863
- precision: 0.8161,
40864
- lastCalibratedAt: "2026-06-27T12:00:00Z",
42677
+ "security/missing-auth-check": {
42678
+ recall: 5e-4,
42679
+ fpRate: 0,
42680
+ ratio: 99999,
42681
+ precision: 1,
42682
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
40865
42683
  verdict: "USEFUL",
40866
- _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.",
40867
- aiSpecific: true
42684
+ _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).",
42685
+ aiSpecific: false,
42686
+ _v7Verdict: "DORMANT",
42687
+ _v7Lift: 1,
42688
+ _v7Recall: 0,
42689
+ _v7FpRate: 0,
42690
+ _v7Precision: 0,
42691
+ _v8Verdict: "USEFUL",
42692
+ _v8Lift: 99999
40868
42693
  },
40869
- "ai/fetch-default-overuse": {
40870
- recall: 28e-4,
40871
- fpRate: 4e-4,
40872
- ratio: 6.76,
40873
- precision: 0.8976,
40874
- lastCalibratedAt: "2026-06-27T12:00:00Z",
42694
+ "security/public-admin-route": {
42695
+ recall: 38e-4,
42696
+ fpRate: 38e-4,
42697
+ ratio: 142.2,
42698
+ precision: 0.5376,
42699
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
40875
42700
  verdict: "USEFUL",
40876
- _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.",
40877
- aiSpecific: true
42701
+ _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).",
42702
+ aiSpecific: false,
42703
+ _v7Verdict: "DORMANT",
42704
+ _v7Lift: 1,
42705
+ _v7Recall: 0,
42706
+ _v7FpRate: 0,
42707
+ _v7Precision: 0,
42708
+ _v8Verdict: "USEFUL",
42709
+ _v8Lift: 38.74
40878
42710
  },
40879
- "ai/console-debug-storm": {
40880
- recall: 8e-3,
40881
- fpRate: 9e-4,
40882
- ratio: 8.43,
40883
- precision: 0.9161,
40884
- lastCalibratedAt: "2026-06-27T12:00:00Z",
42711
+ "security/sql-construction": {
42712
+ recall: 32e-4,
42713
+ fpRate: 15e-4,
42714
+ ratio: 485.42,
42715
+ precision: 0.7183,
42716
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
40885
42717
  verdict: "USEFUL",
40886
- _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.",
40887
- aiSpecific: true
42718
+ _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).",
42719
+ aiSpecific: true,
42720
+ _v7Verdict: "USEFUL",
42721
+ _v7Lift: 370.52,
42722
+ _v7Recall: 3e-3,
42723
+ _v7FpRate: 18e-4,
42724
+ _v7Precision: 0.6788,
42725
+ _v8Verdict: "USEFUL",
42726
+ _v8Lift: 1608.86
40888
42727
  },
40889
- "db/missing-fk-index": {
40890
- recall: 0,
42728
+ "security/target-blank-no-noopener": {
42729
+ recall: 4e-4,
40891
42730
  fpRate: 0,
40892
- ratio: 0,
40893
- precision: 0,
40894
- lastCalibratedAt: "2026-06-30T00:00:00Z",
40895
- verdict: "DORMANT",
40896
- defaultOff: true,
40897
- _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.)",
40898
- aiSpecific: false
42731
+ ratio: 26141.63,
42732
+ precision: 0.9333,
42733
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
42734
+ verdict: "USEFUL",
42735
+ _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).",
42736
+ aiSpecific: false,
42737
+ _v7Verdict: "DORMANT",
42738
+ _v7Lift: 1,
42739
+ _v7Recall: 0,
42740
+ _v7FpRate: 0,
42741
+ _v7Precision: 0,
42742
+ _v8Verdict: "USEFUL",
42743
+ _v8Lift: 7121.02
40899
42744
  },
40900
- "db/duplicate-index": {
40901
- recall: 0,
40902
- fpRate: 0,
40903
- ratio: 0,
40904
- precision: 0,
40905
- lastCalibratedAt: "2026-06-30T00:00:00Z",
40906
- verdict: "DORMANT",
40907
- defaultOff: true,
40908
- _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.)",
40909
- aiSpecific: false
42745
+ "security/unsafe-html-render": {
42746
+ recall: 13e-4,
42747
+ fpRate: 11e-4,
42748
+ ratio: 513.12,
42749
+ precision: 0.574,
42750
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
42751
+ verdict: "USEFUL",
42752
+ _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).",
42753
+ aiSpecific: false,
42754
+ _v7Verdict: "USEFUL",
42755
+ _v7Lift: 757.74,
42756
+ _v7Recall: 13e-4,
42757
+ _v7FpRate: 9e-4,
42758
+ _v7Precision: 0.661,
42759
+ _v8Verdict: "OK",
42760
+ _v8Lift: 201.44
40910
42761
  },
40911
- "db/missing-not-null": {
40912
- recall: 0,
42762
+ "test/duplicate-setup": {
42763
+ recall: 1e-4,
40913
42764
  fpRate: 0,
40914
- ratio: 0,
40915
- precision: 0,
40916
- lastCalibratedAt: "2026-06-30T00:00:00Z",
40917
- verdict: "DORMANT",
40918
- defaultOff: true,
40919
- _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.)",
40920
- aiSpecific: false
42765
+ ratio: 51016.19,
42766
+ precision: 0.8095,
42767
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
42768
+ verdict: "USEFUL",
42769
+ _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).",
42770
+ aiSpecific: true,
42771
+ _v7Verdict: "USEFUL",
42772
+ _v7Lift: 50348.67,
42773
+ _v7Recall: 1e-4,
42774
+ _v7FpRate: 0,
42775
+ _v7Precision: 0.8235,
42776
+ _v8Verdict: "USEFUL",
42777
+ _v8Lift: 51500.25
40921
42778
  },
40922
- "db/enum-sprawl": {
40923
- recall: 0,
40924
- fpRate: 0,
40925
- ratio: 0,
40926
- precision: 0,
40927
- lastCalibratedAt: "2026-06-30T00:00:00Z",
40928
- verdict: "DORMANT",
40929
- defaultOff: true,
40930
- _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.)",
40931
- aiSpecific: false
42779
+ "test/fake-placeholder": {
42780
+ recall: 51e-4,
42781
+ fpRate: 15e-4,
42782
+ ratio: 547.47,
42783
+ precision: 0.8014,
42784
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
42785
+ verdict: "USEFUL",
42786
+ _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).",
42787
+ aiSpecific: true,
42788
+ _v7Verdict: "USEFUL",
42789
+ _v7Lift: 418.76,
42790
+ _v7Recall: 53e-4,
42791
+ _v7FpRate: 19e-4,
42792
+ _v7Precision: 0.7854,
42793
+ _v8Verdict: "USEFUL",
42794
+ _v8Lift: 2477.4
40932
42795
  },
40933
- "db/naming-inconsistency": {
42796
+ "test/missing-edge-case": {
40934
42797
  recall: 0,
40935
42798
  fpRate: 0,
40936
42799
  ratio: 0,
40937
42800
  precision: 0,
40938
- lastCalibratedAt: "2026-06-30T00:00:00Z",
42801
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
40939
42802
  verdict: "DORMANT",
40940
- defaultOff: true,
40941
- _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.)",
40942
- aiSpecific: false
42803
+ _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.",
42804
+ aiSpecific: true,
42805
+ _v7Verdict: "DORMANT",
42806
+ _v7Lift: 0,
42807
+ _v7Recall: 0,
42808
+ _v7FpRate: 0,
42809
+ _v7Precision: 0,
42810
+ _v8Verdict: "DORMANT",
42811
+ _v8Lift: 1,
42812
+ defaultOff: true
40943
42813
  },
40944
- "db/sql-concat": {
40945
- recall: 0,
40946
- fpRate: 0,
40947
- ratio: 0,
40948
- precision: 0,
40949
- lastCalibratedAt: "2026-06-30T00:00:00Z",
40950
- verdict: "DORMANT",
40951
- defaultOff: true,
40952
- _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.)",
40953
- aiSpecific: true
42814
+ "test/weak-assertion": {
42815
+ recall: 0.0417,
42816
+ fpRate: 67e-4,
42817
+ ratio: 131.62,
42818
+ precision: 0.8793,
42819
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
42820
+ verdict: "USEFUL",
42821
+ _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).",
42822
+ aiSpecific: true,
42823
+ _v7Verdict: "USEFUL",
42824
+ _v7Lift: 99.9,
42825
+ _v7Recall: 0.0418,
42826
+ _v7FpRate: 86e-4,
42827
+ _v7Precision: 0.8622,
42828
+ _v8Verdict: "USEFUL",
42829
+ _v8Lift: 651.94
40954
42830
  },
40955
- "dead/unused-import": {
42831
+ "typo/calc-fontsize": {
40956
42832
  recall: 0,
40957
42833
  fpRate: 0,
40958
42834
  ratio: 0,
40959
42835
  precision: 0,
40960
- lastCalibratedAt: "2026-06-30T00:00:00Z",
42836
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
40961
42837
  verdict: "DORMANT",
40962
- defaultOff: true,
40963
- _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.",
40964
- aiSpecific: true
42838
+ _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.",
42839
+ aiSpecific: false,
42840
+ _v7Verdict: "DORMANT",
42841
+ _v7Lift: 0,
42842
+ _v7Recall: 0,
42843
+ _v7FpRate: 0,
42844
+ _v7Precision: 0,
42845
+ _v8Verdict: "DORMANT",
42846
+ _v8Lift: 1,
42847
+ defaultOff: true
40965
42848
  },
40966
- "dead/unused-local": {
42849
+ "typo/calc-raw-px": {
40967
42850
  recall: 0,
40968
42851
  fpRate: 0,
40969
- ratio: 0,
40970
- precision: 0,
40971
- lastCalibratedAt: "2026-06-30T00:00:00Z",
40972
- verdict: "DORMANT",
40973
- defaultOff: true,
40974
- _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).",
40975
- aiSpecific: true
42852
+ ratio: 210066.67,
42853
+ precision: 0.8333,
42854
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
42855
+ verdict: "USEFUL",
42856
+ _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).",
42857
+ aiSpecific: false,
42858
+ _v7Verdict: "USEFUL",
42859
+ _v7Lift: 137559.75,
42860
+ _v7Recall: 0,
42861
+ _v7FpRate: 0,
42862
+ _v7Precision: 0.75,
42863
+ _v8Verdict: "USEFUL",
42864
+ _v8Lift: 99999
40976
42865
  },
40977
- "dead/unused-parameter": {
42866
+ "typo/clamp-offscale": {
40978
42867
  recall: 0,
40979
42868
  fpRate: 0,
40980
42869
  ratio: 0,
40981
42870
  precision: 0,
40982
- lastCalibratedAt: "2026-06-30T00:00:00Z",
42871
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
40983
42872
  verdict: "DORMANT",
40984
- defaultOff: true,
40985
- _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.",
40986
- aiSpecific: true
42873
+ _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.",
42874
+ aiSpecific: false,
42875
+ _v7Verdict: "DORMANT",
42876
+ _v7Lift: 0,
42877
+ _v7Recall: 0,
42878
+ _v7FpRate: 0,
42879
+ _v7Precision: 0,
42880
+ _v8Verdict: "DORMANT",
42881
+ _v8Lift: 1,
42882
+ defaultOff: true
40987
42883
  },
40988
- "dead/dead-branch": {
40989
- recall: 0,
40990
- fpRate: 0,
40991
- ratio: 0,
40992
- precision: 0,
40993
- lastCalibratedAt: "2026-06-30T00:00:00Z",
40994
- verdict: "DORMANT",
40995
- defaultOff: true,
40996
- _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.",
40997
- aiSpecific: true
42884
+ "typo/math-button-label-uniformity": {
42885
+ recall: 1e-4,
42886
+ fpRate: 1e-4,
42887
+ ratio: 6894.19,
42888
+ precision: 0.629,
42889
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
42890
+ verdict: "USEFUL",
42891
+ _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).",
42892
+ aiSpecific: false,
42893
+ _v7Verdict: "USEFUL",
42894
+ _v7Lift: 5571.66,
42895
+ _v7Recall: 2e-4,
42896
+ _v7FpRate: 1e-4,
42897
+ _v7Precision: 0.6379,
42898
+ _v8Verdict: "USEFUL",
42899
+ _v8Lift: 17166.75
40998
42900
  },
40999
- "dead/unreachable": {
42901
+ "typo/math-cta-vocabulary": {
41000
42902
  recall: 0,
41001
42903
  fpRate: 0,
41002
42904
  ratio: 0,
41003
42905
  precision: 0,
41004
- lastCalibratedAt: "2026-06-30T00:00:00Z",
42906
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
41005
42907
  verdict: "DORMANT",
41006
- defaultOff: true,
41007
- _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.",
41008
- aiSpecific: true
42908
+ _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.",
42909
+ aiSpecific: true,
42910
+ _v7Verdict: "DORMANT",
42911
+ _v7Lift: 0,
42912
+ _v7Recall: 0,
42913
+ _v7FpRate: 0,
42914
+ _v7Precision: 0,
42915
+ _v8Verdict: "DORMANT",
42916
+ _v8Lift: 1,
42917
+ defaultOff: true
41009
42918
  },
41010
- "docs/stale-package-reference": {
41011
- recall: 0,
42919
+ "typo/placeholder-text": {
42920
+ recall: 1e-4,
41012
42921
  fpRate: 0,
41013
- ratio: 0,
41014
- precision: 0,
41015
- lastCalibratedAt: "2026-06-30T00:00:00Z",
41016
- verdict: "DORMANT",
41017
- defaultOff: true,
41018
- _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.)",
41019
- aiSpecific: false
42922
+ ratio: 17330.5,
42923
+ precision: 0.6875,
42924
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
42925
+ verdict: "USEFUL",
42926
+ _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).",
42927
+ aiSpecific: false,
42928
+ _v7Verdict: "DORMANT",
42929
+ _v7Lift: 1,
42930
+ _v7Recall: 0,
42931
+ _v7FpRate: 0,
42932
+ _v7Precision: 0,
42933
+ _v8Verdict: "USEFUL",
42934
+ _v8Lift: 4720.86
41020
42935
  },
41021
- "docs/stale-function-reference": {
42936
+ "visual/arbitrary-escape": {
42937
+ recall: 26e-4,
42938
+ fpRate: 7e-4,
42939
+ ratio: 1219.67,
42940
+ precision: 0.8177,
42941
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
42942
+ verdict: "USEFUL",
42943
+ _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).",
42944
+ aiSpecific: true,
42945
+ _v7Verdict: "USEFUL",
42946
+ _v7Lift: 846.78,
42947
+ _v7Recall: 25e-4,
42948
+ _v7FpRate: 9e-4,
42949
+ _v7Precision: 0.7802,
42950
+ _v8Verdict: "USEFUL",
42951
+ _v8Lift: 99999
42952
+ },
42953
+ "visual/clamp-soup": {
41022
42954
  recall: 0,
41023
42955
  fpRate: 0,
41024
42956
  ratio: 0,
41025
42957
  precision: 0,
41026
- lastCalibratedAt: "2026-06-30T00:00:00Z",
42958
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
41027
42959
  verdict: "DORMANT",
41028
- defaultOff: true,
41029
- _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.)",
41030
- aiSpecific: false
42960
+ _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.",
42961
+ aiSpecific: true,
42962
+ _v7Verdict: "DORMANT",
42963
+ _v7Lift: 0,
42964
+ _v7Recall: 0,
42965
+ _v7FpRate: 0,
42966
+ _v7Precision: 0,
42967
+ _v8Verdict: "DORMANT",
42968
+ _v8Lift: 1,
42969
+ defaultOff: true
41031
42970
  },
41032
- "docs/expired-code-example": {
42971
+ "visual/generic-centering": {
41033
42972
  recall: 0,
41034
42973
  fpRate: 0,
41035
42974
  ratio: 0,
41036
42975
  precision: 0,
41037
- lastCalibratedAt: "2026-06-30T00:00:00Z",
42976
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
41038
42977
  verdict: "DORMANT",
41039
- defaultOff: true,
41040
- _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.)",
41041
- aiSpecific: false
42978
+ _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.",
42979
+ aiSpecific: true,
42980
+ _v7Verdict: "DORMANT",
42981
+ _v7Lift: 0,
42982
+ _v7Recall: 0,
42983
+ _v7FpRate: 0,
42984
+ _v7Precision: 0,
42985
+ _v8Verdict: "DORMANT",
42986
+ _v8Lift: 1,
42987
+ defaultOff: true
41042
42988
  },
41043
- "docs/broken-link": {
41044
- recall: 0,
42989
+ "visual/inline-style-dominance": {
42990
+ recall: 0.0103,
42991
+ fpRate: 52e-4,
42992
+ ratio: 134.59,
42993
+ precision: 0.6983,
42994
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
42995
+ verdict: "USEFUL",
42996
+ _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).",
42997
+ aiSpecific: false,
42998
+ _v7Verdict: "USEFUL",
42999
+ _v7Lift: 98.17,
43000
+ _v7Recall: 97e-4,
43001
+ _v7FpRate: 67e-4,
43002
+ _v7Precision: 0.6535,
43003
+ _v8Verdict: "USEFUL",
43004
+ _v8Lift: 704.71
43005
+ },
43006
+ "visual/math-color-cluster": {
43007
+ recall: 2e-4,
41045
43008
  fpRate: 0,
41046
- ratio: 0,
41047
- precision: 0,
41048
- lastCalibratedAt: "2026-06-30T00:00:00Z",
41049
- verdict: "DORMANT",
41050
- defaultOff: true,
41051
- _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.)",
41052
- aiSpecific: false
43009
+ ratio: 46814.86,
43010
+ precision: 0.9286,
43011
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
43012
+ verdict: "USEFUL",
43013
+ _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).",
43014
+ aiSpecific: true,
43015
+ _v7Verdict: "USEFUL",
43016
+ _v7Lift: 33771.28,
43017
+ _v7Recall: 2e-4,
43018
+ _v7FpRate: 0,
43019
+ _v7Precision: 0.9206,
43020
+ _v8Verdict: "USEFUL",
43021
+ _v8Lift: 99999
41053
43022
  },
41054
- "security/eval": {
43023
+ "visual/math-default-font": {
43024
+ recall: 16e-4,
43025
+ fpRate: 3e-4,
43026
+ ratio: 3035.16,
43027
+ precision: 0.8669,
43028
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
43029
+ verdict: "USEFUL",
43030
+ _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).",
43031
+ aiSpecific: true,
43032
+ _v7Verdict: "USEFUL",
43033
+ _v7Lift: 2105.64,
43034
+ _v7Recall: 13e-4,
43035
+ _v7FpRate: 4e-4,
43036
+ _v7Precision: 0.8151,
43037
+ _v8Verdict: "USEFUL",
43038
+ _v8Lift: 68229.63
43039
+ },
43040
+ "visual/math-font-entropy": {
43041
+ recall: 52e-4,
43042
+ fpRate: 1e-3,
43043
+ ratio: 869.95,
43044
+ precision: 0.8593,
43045
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
43046
+ verdict: "USEFUL",
43047
+ _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).",
43048
+ aiSpecific: true,
43049
+ _v7Verdict: "USEFUL",
43050
+ _v7Lift: 600.09,
43051
+ _v7Recall: 45e-4,
43052
+ _v7FpRate: 14e-4,
43053
+ _v7Precision: 0.8114,
43054
+ _v8Verdict: "USEFUL",
43055
+ _v8Lift: 68516.08
43056
+ },
43057
+ "visual/math-gradient-hue-rotation": {
41055
43058
  recall: 0,
41056
43059
  fpRate: 0,
41057
43060
  ratio: 0,
41058
43061
  precision: 0,
41059
- lastCalibratedAt: "2026-06-30T00:00:00Z",
43062
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
41060
43063
  verdict: "DORMANT",
41061
- defaultOff: true,
41062
- _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.)",
41063
- aiSpecific: false
43064
+ _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.",
43065
+ aiSpecific: true,
43066
+ _v7Verdict: "DORMANT",
43067
+ _v7Lift: 0,
43068
+ _v7Recall: 0,
43069
+ _v7FpRate: 0,
43070
+ _v7Precision: 0,
43071
+ _v8Verdict: "DORMANT",
43072
+ _v8Lift: 1,
43073
+ defaultOff: true
41064
43074
  },
41065
- "security/localstorage-token": {
41066
- recall: 0,
43075
+ "visual/math-rounded-entropy": {
43076
+ recall: 38e-4,
43077
+ fpRate: 2e-4,
43078
+ ratio: 3785.45,
43079
+ precision: 0.9461,
43080
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
43081
+ verdict: "USEFUL",
43082
+ _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).",
43083
+ aiSpecific: true,
43084
+ _v7Verdict: "USEFUL",
43085
+ _v7Lift: 2762.74,
43086
+ _v7Recall: 37e-4,
43087
+ _v7FpRate: 3e-4,
43088
+ _v7Precision: 0.9339,
43089
+ _v8Verdict: "USEFUL",
43090
+ _v8Lift: 68368.45
43091
+ },
43092
+ "visual/math-spacing-entropy": {
43093
+ recall: 18e-4,
43094
+ fpRate: 4e-4,
43095
+ ratio: 1898.99,
43096
+ precision: 0.8287,
43097
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
43098
+ verdict: "USEFUL",
43099
+ _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).",
43100
+ aiSpecific: true,
43101
+ _v7Verdict: "USEFUL",
43102
+ _v7Lift: 1339.22,
43103
+ _v7Recall: 18e-4,
43104
+ _v7FpRate: 6e-4,
43105
+ _v7Precision: 0.7959,
43106
+ _v8Verdict: "USEFUL",
43107
+ _v8Lift: 68031.19
43108
+ },
43109
+ "visual/naturalness-anomaly": {
43110
+ recall: 0.1729,
43111
+ fpRate: 0.0687,
43112
+ ratio: 10.86,
43113
+ precision: 0.746,
43114
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
43115
+ verdict: "USEFUL",
43116
+ _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).",
43117
+ aiSpecific: true,
43118
+ _v7Verdict: "USEFUL",
43119
+ _v7Lift: 12.5,
43120
+ _v7Recall: 0.1659,
43121
+ _v7FpRate: 0.0621,
43122
+ _v7Precision: 0.7755,
43123
+ _v8Verdict: "USEFUL",
43124
+ _v8Lift: 7.64
43125
+ },
43126
+ "visual/radius-scale-violation": {
43127
+ recall: 4e-4,
41067
43128
  fpRate: 0,
41068
- ratio: 0,
41069
- precision: 0,
41070
- lastCalibratedAt: "2026-06-30T00:00:00Z",
41071
- verdict: "DORMANT",
41072
- defaultOff: true,
41073
- _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.)",
41074
- aiSpecific: false
43129
+ ratio: 82131.33,
43130
+ precision: 0.9774,
43131
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
43132
+ verdict: "USEFUL",
43133
+ _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).",
43134
+ aiSpecific: false,
43135
+ _v7Verdict: "USEFUL",
43136
+ _v7Lift: 59285.01,
43137
+ _v7Recall: 4e-4,
43138
+ _v7FpRate: 0,
43139
+ _v7Precision: 0.9697,
43140
+ _v8Verdict: "USEFUL",
43141
+ _v8Lift: 99999
41075
43142
  },
41076
- "security/target-blank-no-noopener": {
43143
+ "visual/spacing-scale-violation": {
43144
+ recall: 86e-4,
43145
+ fpRate: 28e-4,
43146
+ ratio: 273.97,
43147
+ precision: 0.7792,
43148
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
43149
+ verdict: "USEFUL",
43150
+ _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).",
43151
+ aiSpecific: false,
43152
+ _v7Verdict: "USEFUL",
43153
+ _v7Lift: 187.83,
43154
+ _v7Recall: 84e-4,
43155
+ _v7FpRate: 39e-4,
43156
+ _v7Precision: 0.7342,
43157
+ _v8Verdict: "USEFUL",
43158
+ _v8Lift: 99999
43159
+ },
43160
+ "wcag/dragging-movements": {
41077
43161
  recall: 0,
41078
43162
  fpRate: 0,
41079
- ratio: 0,
41080
- precision: 0,
41081
- lastCalibratedAt: "2026-06-30T00:00:00Z",
41082
- verdict: "DORMANT",
41083
- defaultOff: true,
41084
- _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.)',
41085
- aiSpecific: false
43163
+ ratio: 33610.67,
43164
+ precision: 0.4,
43165
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
43166
+ verdict: "OK",
43167
+ _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).",
43168
+ aiSpecific: false,
43169
+ _v7Verdict: "OK",
43170
+ _v7Lift: 24455.07,
43171
+ _v7Recall: 0,
43172
+ _v7FpRate: 0,
43173
+ _v7Precision: 0.4,
43174
+ _v8Verdict: "DORMANT",
43175
+ _v8Lift: 1
43176
+ },
43177
+ "wcag/focus-appearance": {
43178
+ recall: 28e-4,
43179
+ fpRate: 1e-4,
43180
+ ratio: 8397.24,
43181
+ precision: 0.966,
43182
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
43183
+ verdict: "USEFUL",
43184
+ _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).",
43185
+ aiSpecific: false,
43186
+ _v7Verdict: "USEFUL",
43187
+ _v7Lift: 7353.82,
43188
+ _v7Recall: 26e-4,
43189
+ _v7FpRate: 1e-4,
43190
+ _v7Precision: 0.9623,
43191
+ _v8Verdict: "USEFUL",
43192
+ _v8Lift: 13418.41
43193
+ },
43194
+ "wcag/focus-obscured": {
43195
+ recall: 33e-4,
43196
+ fpRate: 7e-4,
43197
+ ratio: 1214.21,
43198
+ precision: 0.8478,
43199
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
43200
+ verdict: "USEFUL",
43201
+ _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).",
43202
+ aiSpecific: false,
43203
+ _v7Verdict: "USEFUL",
43204
+ _v7Lift: 859.38,
43205
+ _v7Recall: 34e-4,
43206
+ _v7FpRate: 1e-3,
43207
+ _v7Precision: 0.82,
43208
+ _v8Verdict: "USEFUL",
43209
+ _v8Lift: 68293.81
41086
43210
  },
41087
43211
  "wcag/missing-alt": {
41088
- recall: 0,
41089
- fpRate: 0,
41090
- ratio: 0,
41091
- precision: 0,
41092
- lastCalibratedAt: "2026-06-30T00:00:00Z",
41093
- verdict: "DORMANT",
41094
- defaultOff: true,
41095
- _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.)',
41096
- aiSpecific: false
43212
+ recall: 11e-4,
43213
+ fpRate: 7e-4,
43214
+ ratio: 935.33,
43215
+ precision: 0.6456,
43216
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
43217
+ verdict: "USEFUL",
43218
+ _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).",
43219
+ aiSpecific: false,
43220
+ _v7Verdict: "DORMANT",
43221
+ _v7Lift: 1,
43222
+ _v7Recall: 0,
43223
+ _v7FpRate: 0,
43224
+ _v7Precision: 0,
43225
+ _v8Verdict: "USEFUL",
43226
+ _v8Lift: 254.79
41097
43227
  },
41098
- "typo/placeholder-text": {
43228
+ "wcag/target-size": {
41099
43229
  recall: 0,
41100
43230
  fpRate: 0,
41101
43231
  ratio: 0,
41102
43232
  precision: 0,
41103
- lastCalibratedAt: "2026-06-30T00:00:00Z",
43233
+ lastCalibratedAt: "2026-07-01T00:00:00Z",
41104
43234
  verdict: "DORMANT",
41105
- defaultOff: true,
41106
- _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.)",
41107
- aiSpecific: false
43235
+ _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.",
43236
+ aiSpecific: false,
43237
+ _v7Verdict: "DORMANT",
43238
+ _v7Lift: 0,
43239
+ _v7Recall: 0,
43240
+ _v7FpRate: 0,
43241
+ _v7Precision: 0,
43242
+ _v8Verdict: "DORMANT",
43243
+ _v8Lift: 1,
43244
+ defaultOff: true
41108
43245
  }
41109
43246
  };
41110
43247
 
@@ -41143,7 +43280,6 @@ async function scanFile(filePath, config, registry, cwd = process.cwd()) {
41143
43280
  ".kt",
41144
43281
  ".kts",
41145
43282
  ".dart",
41146
- ".rs",
41147
43283
  ".cpp",
41148
43284
  ".cc",
41149
43285
  ".cxx",