{
  "dimension": "correctness",
  "prefix": "CORR",
  "description": "Rules for detecting logical errors, null handling, and error handling issues",
  "rules": [
    {
      "id": "null-check",
      "category": "null-check",
      "severity": "high",
      "pattern": "\\w+\\.\\w+(?!\\.?\\?)",
      "patternType": "regex",
      "negativePatterns": ["\\?\\.", "if\\s*\\(", "!==?\\s*null", "!==?\\s*undefined", "&&\\s*\\w+\\."],
      "description": "Property access without null/undefined check may cause runtime errors",
      "recommendation": "Add null/undefined check before accessing properties using optional chaining or conditional checks",
      "fixExample": "// Before\nobj.property.value\n\n// After\nobj?.property?.value\n// or\nif (obj && obj.property) { obj.property.value }"
    },
    {
      "id": "empty-catch",
      "category": "empty-catch",
      "severity": "high",
      "pattern": "catch\\s*\\([^)]*\\)\\s*\\{\\s*\\}",
      "patternType": "regex",
      "description": "Empty catch block silently swallows errors, hiding bugs and making debugging difficult",
      "recommendation": "Log the error, rethrow it, or handle it appropriately. Never silently ignore exceptions",
      "fixExample": "// Before\ncatch (e) { }\n\n// After\ncatch (e) {\n  console.error('Operation failed:', e);\n  throw e; // or handle appropriately\n}"
    },
    {
      "id": "unreachable-code",
      "category": "unreachable-code",
      "severity": "medium",
      "pattern": "return\\s+[^;]+;\\s*\\n\\s*[^}\\s]",
      "patternType": "regex",
      "description": "Code after return statement is unreachable and will never execute",
      "recommendation": "Remove unreachable code or restructure the logic to ensure all code paths are accessible",
      "fixExample": "// Before\nfunction example() {\n  return value;\n  doSomething(); // unreachable\n}\n\n// After\nfunction example() {\n  doSomething();\n  return value;\n}"
    },
    {
      "id": "array-index-unchecked",
      "category": "boundary-check",
      "severity": "high",
      "pattern": "\\[\\d+\\]|\\[\\w+\\](?!\\s*[!=<>])",
      "patternType": "regex",
      "negativePatterns": ["\\.length", "Array\\.isArray", "\\?.\\["],
      "description": "Array index access without boundary check may cause undefined access or out-of-bounds errors",
      "recommendation": "Check array length or use optional chaining before accessing array elements",
      "fixExample": "// Before\nconst item = arr[index];\n\n// After\nconst item = arr?.[index];\n// or\nconst item = index < arr.length ? arr[index] : defaultValue;"
    },
    {
      "id": "comparison-type-coercion",
      "category": "type-safety",
      "severity": "medium",
      "pattern": "[^!=]==[^=]|[^!]==[^=]",
      "patternType": "regex",
      "negativePatterns": ["===", "!=="],
      "description": "Using == instead of === can lead to unexpected type coercion",
      "recommendation": "Use strict equality (===) to avoid implicit type conversion",
      "fixExample": "// Before\nif (value == null)\nif (a == b)\n\n// After\nif (value === null || value === undefined)\nif (a === b)"
    }
  ]
}
