{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "version": "1.0.0",
  "lastUpdated": "2026-01-27",
  "description": "Structured reference for AI coding assistants working with EK9",
  "documentation": "https://ek9.io/forAI.html",

  "excludedFeatures": {
    "description": "Features deliberately excluded from EK9 based on production bug evidence",
    "features": [
      {
        "keyword": "break",
        "errorCode": "E01070",
        "errorUrl": "https://ek9.io/errors.html#E01070",
        "reason": "15% of C# bugs (Microsoft 2011), 200+ Linux kernel CVEs",
        "alternative": "Stream pipelines with 'head' or guard expressions",
        "example": {
          "wrong": "for item in items\n  if item.matches()\n    break",
          "correct": "result <- cat items | filter by matches | head"
        },
        "documentation": "https://ek9.io/flowControl.html#streams"
      },
      {
        "keyword": "continue",
        "errorCode": "E01071",
        "errorUrl": "https://ek9.io/errors.html#E01071",
        "reason": "15% of C# bugs (Microsoft 2011), 3x higher defect density",
        "alternative": "Stream pipelines with 'filter' or 'reject'",
        "example": {
          "wrong": "for item in items\n  if not item.isValid()\n    continue\n  process(item)",
          "correct": "cat items | filter by isValid | for each as item\n  process(item)"
        },
        "documentation": "https://ek9.io/flowControl.html#streams"
      },
      {
        "keyword": "return",
        "errorCode": "E01072",
        "errorUrl": "https://ek9.io/errors.html#E01072",
        "reason": "Apple SSL bug (2014), 23% of resource leaks (Google study)",
        "alternative": "Return declarations with '<-' and guard expressions",
        "example": {
          "wrong": "process()\n  -> content as String\n  <- result as String?\n  if not content?\n    return \"\"",
          "correct": "process()\n  -> content as String\n  <- result as String: String()\n  if content?\n    result: transform(content)"
        },
        "documentation": "https://ek9.io/flowControl.html#guards"
      },
      {
        "keyword": "null",
        "errorCode": "E01073",
        "errorUrl": "https://ek9.io/errors.html#E01073",
        "reason": "Billion-dollar mistake (Hoare), #1 Java exception",
        "alternative": "Tri-state semantics (absent/unset/set) with '?' operator",
        "example": {
          "wrong": "name <- null",
          "correct": "name <- String()  // Creates UNSET String\nif name?\n  process(name)  // Safe - guaranteed set"
        },
        "documentation": "https://ek9.io/basics.html#tri-state"
      },
      {
        "keyword": ";",
        "name": "semicolon",
        "errorCode": "E01074",
        "errorUrl": "https://ek9.io/errors.html#E01074",
        "reason": "Indentation-based syntax (like Python)",
        "alternative": "Simply remove - EK9 uses newlines and indentation",
        "example": {
          "wrong": "name <- \"Steve\";",
          "correct": "name <- \"Steve\""
        },
        "documentation": "https://ek9.io/structure.html#indentation"
      },
      {
        "keyword": "new",
        "errorCode": "E01075",
        "errorUrl": "https://ek9.io/errors.html#E01075",
        "reason": "EK9 uses TypeName() directly without 'new' keyword",
        "alternative": "Call type constructor directly: Person() instead of new Person()",
        "example": {
          "wrong": "person <- new Person(\"Steve\")",
          "correct": "person <- Person(\"Steve\")"
        },
        "documentation": "https://ek9.io/basics.html#construction"
      },
      {
        "keyword": "goto",
        "errorCode": "E01076",
        "errorUrl": "https://ek9.io/errors.html#E01076",
        "reason": "Dijkstra (1968) 'Go To Statement Considered Harmful', Apple SSL bug (2014)",
        "alternative": "Use structured control flow: try/finally, guard expressions",
        "example": {
          "wrong": "if error\n  goto cleanup",
          "correct": "try\n  riskyOperation()\nfinally\n  cleanup()"
        },
        "documentation": "https://ek9.io/flowControl.html#structured"
      },
      {
        "keyword": "def",
        "errorCode": "E01077",
        "errorUrl": "https://ek9.io/errors.html#E01077",
        "reason": "EK9 defines functions by name directly without keyword (Python syntax excluded)",
        "alternative": "Start with function name directly, use -> for parameters, <- for returns",
        "example": {
          "wrong": "def greet(name as String)\n  stdout.println(\"Hello \" + name)",
          "correct": "greet()\n  -> name as String\n  stdout.println(\"Hello \" + name)"
        },
        "documentation": "https://ek9.io/functions.html"
      },
      {
        "keyword": "elif",
        "errorCode": "E01078",
        "errorUrl": "https://ek9.io/errors.html#E01078",
        "reason": "EK9 uses 'else if' as two words for readability (Python syntax excluded)",
        "alternative": "Use 'else if' (two separate words)",
        "example": {
          "wrong": "if x > 10\n  big()\nelif x > 5\n  medium()",
          "correct": "if x > 10\n  big()\nelse if x > 5\n  medium()"
        },
        "documentation": "https://ek9.io/flowControl.html#if"
      },
      {
        "keyword": "None",
        "errorCode": "E01079",
        "errorUrl": "https://ek9.io/errors.html#E01079",
        "reason": "Python's None equivalent - EK9 uses tri-state semantics instead",
        "alternative": "Use TypeName() for unset values, '?' operator to check if set",
        "example": {
          "wrong": "name <- None",
          "correct": "name <- String()  // Creates UNSET String\nif name?\n  process(name)"
        },
        "documentation": "https://ek9.io/basics.html#tri-state"
      },
      {
        "keyword": "self",
        "errorCode": "E01080",
        "errorUrl": "https://ek9.io/errors.html#E01080",
        "reason": "EK9 uses 'this' instead of 'self' (Java/C++/JavaScript convention)",
        "alternative": "Use 'this' keyword, or omit when unambiguous",
        "example": {
          "wrong": "greet()\n  stdout.println(\"I am \" + self.name)",
          "correct": "greet()\n  stdout.println(\"I am \" + this.name)\n  // Or simply: \"I am \" + name"
        },
        "documentation": "https://ek9.io/classes.html#this"
      },
      {
        "keyword": "listComprehension",
        "name": "Python list comprehension",
        "pattern": "[x for x in items]",
        "errorCode": "E01081",
        "errorUrl": "https://ek9.io/errors.html#E01081",
        "reason": "EK9 uses stream pipelines for composability and lazy evaluation",
        "alternative": "Define function for transformation, use 'cat collection | map with fn | collect as List' pattern",
        "example": {
          "wrong": "squares <- [x * x for x in numbers]",
          "correct": "squareIt() -> n as Integer <- result as Integer: n * n\nsquares <- cat numbers | map with squareIt | collect as List of Integer"
        },
        "documentation": "https://ek9.io/streamsAndPipelines.html"
      },
      {
        "keyword": "multipleArgumentArrows",
        "name": "multiple '->' arrows for parameters",
        "pattern": "-> param1 as T1\n-> param2 as T2",
        "errorCode": "E01082",
        "errorUrl": "https://ek9.io/errors.html#E01082",
        "reason": "EK9 uses ONE '->' with indented block for multiple parameters",
        "alternative": "Use single '->' followed by indented parameter block",
        "example": {
          "wrong": "badFunction()\n  -> param1 as String\n  -> param2 as Integer\n  <- result as String",
          "correct": "goodFunction()\n  ->\n    param1 as String\n    param2 as Integer\n  <- result as String"
        },
        "documentation": "https://ek9.io/functions.html#parameters"
      },
      {
        "keyword": "multipleReturnArrows",
        "name": "multiple '<-' arrows for returns",
        "pattern": "<- result1 as T1\n<- result2 as T2",
        "errorCode": "E01083",
        "errorUrl": "https://ek9.io/errors.html#E01083",
        "reason": "EK9 functions have exactly ONE return declaration - use records for multiple values",
        "alternative": "Create a record type and return a single instance containing multiple fields",
        "example": {
          "wrong": "badFunction()\n  -> input as String\n  <- result1 as String\n  <- result2 as Integer",
          "correct": "defines record\n  ReturnValues\n    text as String?\n    count as Integer?\n\ndefines function\n  goodFunction()\n    -> input as String\n    <- rtn as ReturnValues: ReturnValues(input, length(input))"
        },
        "documentation": "https://ek9.io/functions.html#returns"
      },
      {
        "keyword": "instanceof",
        "name": "type checking",
        "reason": "Breaks polymorphism, creates brittle code, causes maintenance bugs",
        "alternative": "Use 'dispatcher' methods for type-specific behavior",
        "note": "There is NO way to check types at runtime in EK9 - this is by design",
        "documentation": "https://ek9.io/advancedClassMethods.html#dispatcher"
      },
      {
        "keyword": "casting",
        "name": "type casting",
        "reason": "Breaks type safety, enables ClassCastException-style bugs",
        "alternative": "Use 'dispatcher' methods - compiler routes to correct overload",
        "note": "There is NO way to cast types in EK9 - this is by design",
        "documentation": "https://ek9.io/advancedClassMethods.html#dispatcher"
      },
      {
        "keyword": "const",
        "name": "constant data modifier",
        "reason": "EK9 takes a fundamentally different approach: the constraint is on the OPERATION, not the data",
        "alternative": "Mark functions/methods 'as pure' — compiler prevents all mutation in pure contexts at compile time",
        "note": "Data is NEVER const in EK9. Immutability is contextual: the same List is unmutatable in a pure function but fully mutable in a non-pure function. This preserves the Liskov Substitution Principle — Java's immutable collections break LSP by throwing runtime UnsupportedOperationException",
        "documentation": "https://ek9.io/basics.html#pure"
      },
      {
        "keyword": "final",
        "name": "final/sealed modifier",
        "reason": "EK9 types are CLOSED by default (no 'final' needed). For data immutability, use 'as pure' on operations",
        "alternative": "Types are closed by default — use 'as open' to allow extension. Use 'as pure' for mutation control",
        "note": "Two concepts combined in other languages: (1) Extension prevention — EK9 types are closed by default, use 'as open' to opt in. (2) Data immutability — use 'as pure' on functions/methods, not 'final' on data",
        "documentation": "https://ek9.io/classes.html"
      },
      {
        "keyword": "immutable",
        "name": "immutable data types",
        "reason": "EK9 has NO immutable List, Dict, record, or any data type — and never will. ALL types are mutable",
        "alternative": "Mark functions/methods 'as pure' — compiler prevents mutation at compile time, not runtime",
        "note": "Java's immutable List breaks the Liskov Substitution Principle by throwing UnsupportedOperationException at runtime. EK9 prevents mutation at COMPILE TIME instead. The same object can be: unmutatable when passed to a pure function, fully mutable when passed to a non-pure function. Immutability is contextual, not permanent",
        "documentation": "https://ek9.io/basics.html#pure"
      }
    ]
  },

  "dispatcherPattern": {
    "description": "EK9's replacement for instanceof/casting - the ONLY way to handle type-specific behavior",
    "criticalRule": "There is NO instanceof and NO casting in EK9. Dispatcher is the ONLY mechanism.",
    "howItWorks": "Mark a method 'as dispatcher', provide overloaded methods for specific types, compiler generates dispatch logic",
    "whyMethodsOnly": "Functions cannot be overloaded (names must be unique in module), so dispatcher only works on methods",
    "singleDispatch": {
      "description": "Dispatch on one parameter's runtime type",
      "example": "render() as dispatcher\n  -> shape as Shape\n  shape.draw()\n\nrender()\n  -> circle as Circle\n  // Circle-specific rendering"
    },
    "doubleDispatch": {
      "description": "Dispatch on two parameters' runtime types (visitor pattern replacement)",
      "example": "intersect() as dispatcher\n  -> s1 as Shape\n  -> s2 as Shape\n  <- result as Intersection?\n\nintersect()\n  -> s1 as Circle\n  -> s2 as Circle\n  <- result as Intersection: ArcIntersection()"
    },
    "ambiguityDetection": {
      "description": "Compiler detects ambiguous dispatch and requires explicit resolution",
      "example": "If Square implements T1 and T2, and you have render(T1) and render(T2), compiler requires render(Square) to disambiguate"
    },
    "fallbackBehavior": "If no specific type match exists, the dispatcher's own implementation is called as default",
    "relatedErrors": ["E07120", "E07820", "E05170", "E05180"],
    "documentation": "https://ek9.io/advancedClassMethods.html#dispatcher"
  },

  "triStateSemantics": {
    "description": "EK9's tri-state object model replaces null",
    "states": [
      {
        "name": "absent",
        "meaning": "Object doesn't exist",
        "example": "Dict key not found"
      },
      {
        "name": "unset",
        "meaning": "Object exists but has no meaningful value",
        "example": "String() creates unset String"
      },
      {
        "name": "set",
        "meaning": "Object exists with valid, usable value",
        "example": "String(\"hello\") is set"
      }
    ],
    "criticalRule": "Collections (List, Dict) are ALWAYS set when created, even if empty. Only primitives (String, Integer) are unset when empty.",
    "operator": "?",
    "operatorMeaning": "Calls _isSet() method to check if value is set",
    "documentation": "https://ek9.io/basics.html#tri-state"
  },

  "closedByDefault": {
    "description": "EK9 types are closed by default (like Kotlin)",
    "errorCode": "E05030",
    "errorUrl": "https://ek9.io/errors.html#E05030",
    "neverExtendable": ["List", "Dict", "DictEntry", "MutexLock", "Optional", "PriorityQueue", "Result"],
    "howToMakeExtendable": "Declare with 'as open' modifier",
    "correctPattern": "Use composition/delegation instead of inheritance",
    "example": {
      "wrong": "MyList extends List of String",
      "correct": "MyList\n  items as List of String\n  add(item as String)\n    items += item"
    },
    "documentation": "https://ek9.io/inheritance.html#closed-by-default"
  },

  "accessModifiers": {
    "description": "EK9 access modifier rules vary by declaration kind - fields, methods, and operators each have different rules",
    "criticalRule": "Fields are ALWAYS private in classes/components (no syntax to change this). Only METHODS support public/protected/private modifiers.",
    "fields": {
      "rule": "Fields (properties) have NO access modifier in the grammar",
      "classFields": "Always private - subclasses cannot access parent fields directly",
      "recordFields": "Always public - records are data structures with public access",
      "componentFields": "Always private - same as class fields",
      "traitFields": "Traits cannot have fields",
      "packageProperties": "Always public within module scope",
      "noProtectedFields": "There is no way to declare a protected field - this is deliberate to avoid the fragile base class problem",
      "subclassAccess": "Use accessor methods (public or protected) to expose parent state to subclasses"
    },
    "methods": {
      "rule": "Methods support optional access modifiers",
      "syntax": "(OVERRIDE | DEFAULT)? accessModifier? identifier ...",
      "defaultAccess": "Public (no modifier needed)",
      "options": ["public", "protected", "private"],
      "protectedMethods": "Accessible from subclasses and same-hierarchy types",
      "privateMethods": "Accessible only within the declaring type"
    },
    "operators": {
      "rule": "Operators have NO access modifier - always public",
      "syntax": "(OVERRIDE | DEFAULT)? OPERATOR operator ...",
      "rationale": "Operators define the public contract of a type"
    },
    "example": {
      "wrong": "defines class\n  MyClass as open\n    protected name <- String()    //WRONG: grammar error, fields cannot have access modifiers",
      "correct": "defines class\n  MyClass as open\n    name <- String()              //Field is always private\n\n    protected getName() as pure   //Use protected method for subclass access\n      <- rtn as String: name\n\n  ChildClass extends MyClass\n    describe()\n      <- rtn as String: getName() //Access parent state via method"
    },
    "errorCodes": {
      "E06180": "Field or method not accessible from this context (private access violation)"
    },
    "documentation": "https://ek9.io/advancedClassMethods.html"
  },

  "assignmentOperators": {
    "description": "Three distinct assignment operators with precise semantics",
    "operators": [
      {
        "operator": "<-",
        "name": "Declaration",
        "semantics": "Create NEW variable + first assignment",
        "useCase": "First-time assignment"
      },
      {
        "operator": ":=",
        "name": "Assignment",
        "semantics": "Assign to EXISTING variable",
        "useCase": "Reassignment"
      },
      {
        "operator": ":=?",
        "name": "Guarded Assignment",
        "semantics": "Only assign if variable is UNSET",
        "useCase": "Conditional initialization"
      }
    ],
    "documentation": "https://ek9.io/basics.html#assignments"
  },

  "guardExpressions": {
    "description": "Guards combine assignment with null/isSet checking",
    "syntax": "if variable <- expression",
    "meaning": "Execute block only if expression result is SET",
    "worksIn": ["if", "switch", "for", "while", "try"],
    "examples": [
      {
        "construct": "if",
        "code": "if name <- getName()\n  stdout.println(name)"
      },
      {
        "construct": "for",
        "code": "for item <- iterator.next()\n  process(item)"
      },
      {
        "construct": "while",
        "code": "while conn <- getActiveConnection()\n  transferData(conn)"
      }
    ],
    "documentation": "https://ek9.io/flowControl.html#guards"
  },

  "qualityMetrics": {
    "description": "Compile-time enforced quality thresholds",
    "metrics": [
      {
        "name": "Cyclomatic Complexity",
        "abbreviation": "CC",
        "good": "<=10",
        "monitor": "11-15",
        "warning": "16-25",
        "limit": 45,
        "errorCode": "E11010",
        "errorUrl": "https://ek9.io/errors.html#E11010"
      },
      {
        "name": "Cognitive Complexity",
        "abbreviation": "Cog",
        "good": "<=10",
        "monitor": "11-15",
        "warning": "16-25",
        "limit": 35,
        "errorCode": "E11021",
        "errorUrl": "https://ek9.io/errors.html#E11021"
      },
      {
        "name": "Nesting Depth",
        "good": "<=2",
        "monitor": "3",
        "warning": "4-5",
        "limit": 6,
        "errorCode": "E11011",
        "errorUrl": "https://ek9.io/errors.html#E11011"
      },
      {
        "name": "Statement Count",
        "good": "<=50",
        "monitor": "51-100",
        "warning": "101-150",
        "limit": 150,
        "errorCode": "E11012",
        "errorUrl": "https://ek9.io/errors.html#E11012"
      },
      {
        "name": "Cohesion (LCOM4)",
        "good": "<=3",
        "monitor": "4-5",
        "warning": "6-8",
        "limit": 8,
        "errorCode": "E11014",
        "errorUrl": "https://ek9.io/errors.html#E11014"
      },
      {
        "name": "Coupling (Ce)",
        "good": "<=5",
        "monitor": "6-8",
        "warning": "9-12",
        "limit": 12,
        "errorCode": "E11015",
        "errorUrl": "https://ek9.io/errors.html#E11015"
      },
      {
        "name": "Inheritance Depth",
        "good": "<=2",
        "monitor": "3",
        "warning": "4",
        "limit": 4,
        "errorCode": "E11019",
        "errorUrl": "https://ek9.io/errors.html#E11019"
      },
      {
        "name": "Coverage",
        "good": ">=80%",
        "monitor": "60-79%",
        "warning": "<60%",
        "limit": "80% for publishing"
      }
    ],
    "documentation": "https://ek9.io/quality.html"
  },

  "bannedIdentifiers": {
    "description": "Variable names banned due to high defect correlation",
    "banned": [
      {"name": "temp", "defectMultiplier": 3.1},
      {"name": "tmp", "defectMultiplier": 3.1},
      {"name": "data", "defectMultiplier": 2.8},
      {"name": "dat", "defectMultiplier": 2.8},
      {"name": "flag", "defectMultiplier": 3.4},
      {"name": "flg", "defectMultiplier": 3.4},
      {"name": "value", "defectMultiplier": 2.9},
      {"name": "val", "defectMultiplier": 2.9}
    ],
    "exceptions": ["Mathematical variables (x, y, theta)", "Loop counters (i, j, k)"],
    "errorCode": "E11031",
    "documentation": "https://ek9.io/quality.html#naming-quality"
  },

  "codeQualityEnforcement": {
    "description": "Compile-time code quality rules unique to EK9. These exist in NO other language — AI will violate them on every attempt unless explicitly told. Ordered by AI violation frequency.",

    "stringInterpolationMandate": {
      "errorCode": "E11068",
      "rule": "3+ part string concatenation is a compile error",
      "rationale": "Forces readable interpolation, prevents unbounded concatenation chains",
      "example": {
        "wrong": "result <- first + \" \" + last",
        "correct": "result <- `${first} ${last}`"
      },
      "note": "2-part concatenation (a + b) is allowed. 3+ parts must use backtick interpolation."
    },

    "namedArgumentEnforcement": {
      "rules": [
        {
          "errorCode": "E11062",
          "rule": "4+ positional arguments require named arguments",
          "example": {
            "wrong": "connect(\"db\", 5432, true, false)",
            "correct": "connect(host: \"db\", port: 5432, ssl: true, compress: false)"
          }
        },
        {
          "errorCode": "E11061",
          "rule": "2+ Boolean literal arguments require named arguments",
          "example": {
            "wrong": "configure(true, false)",
            "correct": "configure(verbose: true, dryRun: false)"
          }
        }
      ],
      "syntax": "paramName: value",
      "note": "No other language mandates named arguments. AI training data contains zero examples of this constraint."
    },

    "magicLiteralDetection": {
      "rules": [
        {
          "errorCode": "E11064",
          "rule": "Bare numeric literal in comparison is a compile error",
          "example": {
            "wrong": "if retries > 3\n  timeout()",
            "correct": "maxRetries <- 3\nif retries > maxRetries\n  timeout()"
          }
        },
        {
          "errorCode": "E11065",
          "rule": "Same literal 3+ times per file or 4+ per module requires named constant",
          "example": {
            "wrong": "x * 3.14\ny * 3.14\nz * 3.14",
            "correct": "pi <- 3.14159\nx * pi\ny * pi\nz * pi"
          }
        }
      ],
      "exemptValues": [0, 1, -1, "0.0", "1.0"],
      "exemptTypes": ["Boolean", "Character", "RegEx", "Binary"],
      "note": "Extract numeric literals to named constants in 'defines constant' block."
    },

    "operatorKeywordShadowing": {
      "errorCode": "E11032",
      "rule": "Variable names that shadow operator keywords are banned",
      "banned": ["empty", "length", "contains", "abs", "sqrt", "close", "matches"],
      "fix": "Use descriptive alternatives: foundItems, isAvailable, searchPattern, textLength",
      "note": "Complements bannedIdentifiers (E11031) which covers non-descriptive names like temp, data, flag."
    },

    "discardedReturnValues": {
      "rules": [
        {
          "errorCode": "E11050",
          "rule": "Discarded operator return is a compile error",
          "example": "price + tax  //ERROR: return value discarded"
        },
        {
          "errorCode": "E11051",
          "rule": "Discarded pure method/function return is a compile error",
          "example": "calculateTotal(items)  //ERROR: return value discarded"
        },
        {
          "errorCode": "E11052",
          "rule": "Discarded Result/Optional return silently swallows errors",
          "example": "parseJSON(input)  //ERROR: Result must be checked"
        }
      ],
      "fix": "Always capture return values: total <- calculateTotal(items)",
      "note": "Many languages allow ignoring return values. EK9 treats this as a bug."
    },

    "tautologicalExpressions": {
      "rules": [
        {"errorCode": "E08080", "rule": "Self-assignment: x := x"},
        {"errorCode": "E08081", "rule": "Self-comparison: x == x"},
        {"errorCode": "E08082", "rule": "Constant comparison: 1 == 1"},
        {"errorCode": "E08083", "rule": "Constant arithmetic: x - x, x / x"},
        {"errorCode": "E08084", "rule": "Redundant Boolean: b == true (use just b)"},
        {"errorCode": "E08085", "rule": "Logical tautology: a or not a"}
      ],
      "note": "AI copy-paste patterns frequently generate tautological expressions."
    },

    "confusinglySimilarNames": {
      "errorCode": "E11030",
      "rule": "Variables differing by 1-2 characters (Levenshtein distance) with same type are banned",
      "examples": ["data/dat", "userId/usersId", "count/counts"],
      "exemptions": ["Different types", "Constructor field shadowing", "Loop counters"],
      "research": "2.7x higher defect density (Butler et al., ICPC 2010)"
    },

    "classDesignAntiPatterns": {
      "rules": [
        {"errorCode": "E11022", "rule": "Class with 4+ service fields and 0 data fields should be 'defines component'"},
        {"errorCode": "E11023", "rule": "70%+ trait methods manually overridden — use 'by' delegation instead"},
        {"errorCode": "E11024", "rule": "'by' delegation + 3+ services — split into class + component"},
        {"errorCode": "E11025", "rule": "3+ services AND 3+ data fields — 'God Class', must decompose"}
      ]
    },

    "diInjectionLimits": {
      "rules": [
        {"errorCode": "E11040", "rule": "Max 4 injection fields per component"},
        {"errorCode": "E11041", "rule": "Similar dependencies should use a facade"},
        {"errorCode": "E11042", "rule": "Max 20 services per application registry"},
        {"errorCode": "E11043", "rule": "Max 5 injected types per method"}
      ],
      "fix": "Split large components into focused sub-components with facades."
    },

    "dataClumpDetection": {
      "errorCode": "E11053",
      "rule": "3+ callables sharing 4+ parameters with matching types/names must extract to a record",
      "fix": "Create a record containing the repeated parameters and pass the record instead."
    },

    "typeTraversalLimit": {
      "errorCode": "E11054",
      "rule": "Max 3 type transitions in a method chain (Law of Demeter)",
      "example": {
        "wrong": "city <- order.getCustomer().getAddress().getCity()",
        "correct": "city <- order.customerCity()"
      },
      "fix": "Delegate through intermediate methods to limit coupling."
    },

    "constantOrganization": {
      "rules": [
        {"errorCode": "E11066", "rule": "Constants scattered across 3+ files in a module must be consolidated"},
        {"errorCode": "E11067", "rule": "2+ files with 10+ total constants need a dedicated constants file"}
      ],
      "fix": "Use a single 'defines constant' block per module."
    },

    "unusedCaptureDetection": {
      "errorCode": "E11018",
      "rule": "Dynamic function/class captures a variable but never uses it",
      "fix": "Remove unused captures from the closure scope."
    },

    "referenceOrdering": {
      "errorCode": "E11026",
      "rule": "References (imports) must be sorted alphabetically",
      "research": "5-10% reduction in merge conflicts."
    }
  },

  "compilation": {
    "description": "EK9 compilation commands and flags",
    "incremental": {
      "compile": "ek9 -c main.ek9",
      "compileDebug": "ek9 -cg main.ek9",
      "compileDevDebug": "ek9 -cd main.ek9"
    },
    "full": {
      "recompile": "ek9 -C main.ek9",
      "recompileDebug": "ek9 -Cg main.ek9",
      "recompileDevDebug": "ek9 -Cd main.ek9",
      "cleanAll": "ek9 -Cl main.ek9"
    },
    "run": {
      "default": "ek9 main.ek9",
      "specificProgram": "ek9 -r ProgramName main.ek9",
      "shebang": "./main.ek9"
    },
    "optimization": {
      "O0": "No optimization (forced with tests)",
      "O1": "Light optimization",
      "O2": "Standard optimization (incompatible with -t)",
      "O3": "Aggressive optimization (incompatible with -t)"
    },
    "errorLevels": {
      "E0": "Minimal - single line",
      "E1": "Visual - Rust-style source display with caret markers",
      "E2": "Visual + 'Did you mean?' fuzzy matching suggestions",
      "E3": "Rich - full AI-oriented explanations with diagnosis, rationale, and examples",
      "E4": "Paradigm - concise summary of key design decisions (no break/continue/return, tri-state, closed types, automatic operators)",
      "E5": "Bootstrap - E4 paradigm summary plus complete forAI.json reference dump. Use once to learn EK9, then switch to E3",
      "E6": "Local agent briefing - slim forAI-local.json operational reference for fine-tuned local LLMs in ek9 -ai. Contains role, Oracle, intents, protocol, terrain, and top reminders (~1900 tokens)"
    },
    "help": {
      "generalHelp": "ek9 -h",
      "keywordHelp": "ek9 -h <keyword>",
      "errorCodeHelp": "ek9 -h Exxxx (e.g., ek9 -h E50001 — shows diagnosis, fix actions, examples for any error code)",
      "listAllKeywords": "ek9 -H",
      "questionAnswer": "ek9 -q <words> (EK9-focused: answer + code example)",
      "questionById": "ek9 -q <number> (fetch specific Q&A by ID, e.g., ek9 -q 45)",
      "questionMigration": "ek9 -qm <words> (migration-focused: answer + language comparisons)",
      "listAllQuestions": "ek9 -q",
      "aiNote": "Use 'ek9 -q <words>' for EK9 syntax and examples. Use 'ek9 -q <number>' to follow cross-links (e.g., 'See Q45'). Use 'ek9 -qm <words>' when comparing EK9 to other languages. Use 'ek9 -h Exxxx' to diagnose compiler errors."
    },
    "diAnalysis": {
      "compact": "ek9 -di main.ek9 (summary: registration counts, injection sites, health status)",
      "rich": "ek9 -di -E3 main.ek9 (full wiring map, injection sites, aspect chains, structured guidance)",
      "aiNote": "Run 'ek9 -di -E3' BEFORE modifying DI wiring to understand current registrations, ordering, and injection field counts"
    },
    "target": "ek9 -T java main.ek9 (Java is only target currently)",
    "verbose": "ek9 -v -c main.ek9",
    "aiRecommendation": "Use -E5 once to bootstrap, then -E3 for ongoing development. Use 'ek9 -h Exxxx' to diagnose any error. Use 'ek9 -di -E3' before modifying DI wiring. Use 'ek9 -q <words>' for EK9 syntax/examples, 'ek9 -qm <words>' for language comparisons.",
    "documentation": "https://ek9.io/commandline.html"
  },

  "testing": {
    "description": "EK9 testing commands, output formats, and coverage",
    "commands": {
      "runTests": "ek9 -t main.ek9",
      "listTests": "ek9 -tL main.ek9",
      "runGroup": "ek9 -tg groupname main.ek9",
      "showCoverage": "ek9 -tC main.ek9",
      "debug": "ek9 -d port main.ek9"
    },
    "outputFormats": {
      "t0": "Terse - for scripting and CI pipelines",
      "t1": "Human-readable (default with -t)",
      "t2": "JSON - programmatic analysis and AI tool integration",
      "t3": "JUnit XML - CI/CD integration",
      "t4": "Detailed coverage report - writes .ek9/coverage-detail.json with file:line for uncovered methods/branches",
      "t5": "Verbose coverage - lists BOTH covered AND uncovered items (for verification and debugging)",
      "t6": "Interactive HTML coverage report - writes .ek9/coverage/index.html with SVG charts, module breakdown, source views, dark/light theme, search, mobile-responsive"
    },
    "testDiscovery": "Programs marked with @Test in /dev directory and subdirectories are auto-discovered",
    "testGroups": "@Test: \"groupname\" syntax allows selective test execution with -tg",
    "coverage": {
      "threshold": "80% - automatic detailed report to .ek9/coverage-detail.json when below",
      "viewResults": "ek9 -tC main.ek9"
    },
    "constraint": "-t cannot be combined with -O2 or -O3 optimization flags",
    "aiRecommendation": "Use -t2 for JSON output in automated workflows, -t for human-readable during development",
    "documentation": "https://ek9.io/commandline.html#testing"
  },

  "packaging": {
    "description": "EK9 dependency management, versioning, packaging, and deployment",
    "dependencies": {
      "resolve": "ek9 -Dp main.ek9",
      "repository": "repo.ek9lang.org",
      "localCache": "$HOME/.ek9/lib",
      "note": "Triggers clean before resolving; dependencies declared in package construct"
    },
    "versioning": {
      "print": "ek9 -PV main.ek9",
      "increment": "ek9 -IV major|minor|patch|build main.ek9",
      "set": "ek9 -SV major.minor.patch main.ek9",
      "setFeature": "ek9 -SF major.minor.patch-feature main.ek9",
      "format": "major.minor.patch-build (e.g., 6.8.1-0) or major.minor.patch-feature-build (e.g., 6.8.0-specials-0)"
    },
    "package": "ek9 -P main.ek9",
    "installLocal": "ek9 -I main.ek9",
    "deploy": {
      "command": "ek9 -D main.ek9",
      "note": "Triggers -P and -Gk automatically",
      "generateKeys": "ek9 -Gk",
      "configFile": "$HOME/.ek9/config",
      "credentialsFile": "$HOME/.ek9/credentials"
    },
    "aiRecommendation": "Use -IV patch for bug fixes, -IV minor for new features, -IV major for breaking changes",
    "documentation": "https://ek9.io/commandline.html#packaging"
  },

  "projectStructure": {
    "description": "EK9 project directory structure and conventions",
    "layout": {
      "main.ek9": "Main source file with package construct defining module, version, and dependencies",
      ".ek9/": "Generated build artifacts directory (auto-created by compiler)",
      "dev/": "Development code — test programs (@Test), examples, templates. Not included in library packaging",
      "$HOME/.ek9/lib/": "Global dependency cache — resolved libraries stored here",
      "$HOME/.ek9/config": "Artifact server settings for deployment",
      "$HOME/.ek9/credentials": "Authentication details for artifact server"
    },
    "packageConstruct": {
      "description": "The package construct in main source declares project metadata and dependencies",
      "example": "defines package\n  version <- 1.0.0-0\n  description <- \"My EK9 library\"\n  deps\n    org.example.lib 2.0.0-0"
    },
    "devDirectory": {
      "description": "Programs in /dev are auto-discovered for testing",
      "convention": "Test files use @Test annotation, groups use @Test: \"groupname\"",
      "excluded": "Dev code is not included when the package is consumed as a library"
    },
    "documentation": "https://ek9.io/packaging.html"
  },

  "languageServer": {
    "description": "EK9 Language Server Protocol (LSP) integration",
    "start": "ek9 -ls main.ek9",
    "startWithHover": "ek9 -lsh main.ek9",
    "protocol": "stdin/stdout LSP protocol",
    "vscodeExtension": "Available for VSCode with syntax highlighting and real-time error reporting",
    "hoverHelp": "-lsh enables hover documentation for operators and symbols",
    "documentation": "https://ek9.io/commandline.html#languageserver"
  },

  "repl": {
    "description": "EK9 interactive Read-Eval-Print Loop",
    "start": "ek9 -repl",
    "startWithSuggestions": "ek9 -repl -E2",
    "modes": ["/function", "/class", "/record", "/trait", "/type"],
    "commands": {
      "edit": ":edit — opens $VISUAL or $EDITOR for multi-line editing",
      "editLine": ":edit N — edit line N in buffer",
      "delete": ":del N — delete line N",
      "insert": ":ins N — insert before line N",
      "undo": ":undo — undo last change",
      "save": ":save — save session",
      "load": ":load — load previous session"
    },
    "hoverHelp": "Ctrl+H shows symbol information in REPL",
    "documentation": "https://ek9.io/commandline.html#repl"
  },

  "environment": {
    "description": "EK9 environment variables and runtime configuration",
    "variables": {
      "EK9_COMPILER_MEMORY": "Compiler heap size (default: -Xmx512m), e.g., export EK9_COMPILER_MEMORY=\"-Xmx1024m\"",
      "EK9_APPLICATION_MEMORY": "Application heap size (default: -Xmx512m), e.g., export EK9_APPLICATION_MEMORY=\"-Xmx2048m\"",
      "EK9_TARGET": "Target architecture (default: java)",
      "EK9_PLAIN_TEXT": "Force plain text error output (no colors, no unicode)"
    },
    "stdinStdout": {
      "description": "EK9 programs integrate with Unix pipes and redirection",
      "examples": [
        "echo \"Hello\" | ek9 program.ek9",
        "ek9 filter.ek9 < input.txt > output.txt",
        "cat data.txt | ek9 filter.ek9 | sort | uniq"
      ],
      "classes": "Stdin(), Stdout(), Stderr()"
    },
    "setEnvFlag": "ek9 -e name=value main.ek9",
    "documentation": "https://ek9.io/commandline.html"
  },

  "exitCodes": {
    "description": "EK9 process exit codes for CI/CD integration and scripting",
    "codes": {
      "0": "Success",
      "1": "Cannot execute",
      "2": "Invalid parameters",
      "3": "File access error",
      "4": "Invalid parameter combination",
      "5": "No programs found in source",
      "6": "Multiple programs exist — use -r to specify",
      "7": "Language Server failed to start",
      "8": "Compilation failed",
      "9": "Wrong number of program arguments",
      "10": "Argument type conversion failed",
      "11": "Test execution failed"
    },
    "ciExample": "ek9 -C main.ek9 && ek9 -t2 main.ek9 > test-results.json && ek9 -D main.ek9",
    "documentation": "https://ek9.io/commandline.html"
  },

  "developmentWorkflow": {
    "description": "Complete EK9 development lifecycle from creation to deployment",
    "steps": [
      {
        "phase": "create",
        "description": "Create source file with package construct defining module, version, and dependencies",
        "command": "touch myapp.ek9"
      },
      {
        "phase": "develop",
        "description": "Iterative development with incremental compilation",
        "command": "ek9 -c myapp.ek9"
      },
      {
        "phase": "diAnalysis",
        "description": "Inspect DI wiring before modifying injection (only if using components/applications)",
        "command": "ek9 -di -E3 myapp.ek9"
      },
      {
        "phase": "errorDiagnosis",
        "description": "Look up any compiler error for full diagnosis and fix actions",
        "command": "ek9 -h Exxxx"
      },
      {
        "phase": "run",
        "description": "Compile and execute the program",
        "command": "ek9 myapp.ek9"
      },
      {
        "phase": "test",
        "description": "Run all test programs in /dev directory",
        "command": "ek9 -t myapp.ek9"
      },
      {
        "phase": "coverage",
        "description": "Check test coverage meets 80% threshold",
        "command": "ek9 -tC myapp.ek9"
      },
      {
        "phase": "resolveDeps",
        "description": "Resolve dependencies from repo.ek9lang.org",
        "command": "ek9 -Dp myapp.ek9"
      },
      {
        "phase": "version",
        "description": "Increment version before release",
        "command": "ek9 -IV minor myapp.ek9"
      },
      {
        "phase": "package",
        "description": "Create deployment package",
        "command": "ek9 -P myapp.ek9"
      },
      {
        "phase": "installLocal",
        "description": "Install to local library for use by other projects",
        "command": "ek9 -I myapp.ek9"
      },
      {
        "phase": "deploy",
        "description": "Deploy to artifact server (generates keys if needed)",
        "command": "ek9 -D myapp.ek9"
      }
    ],
    "documentation": "https://ek9.io/commandline.html"
  },

  "streamPipelines": {
    "description": "EK9's replacement for loops needing break/continue. NOTE: for/while/do-while loops still exist for iteration with mutation, side effects, and I/O",
    "sources": [
      {"name": "cat", "purpose": "Create stream from collection, iterator, or enumeration"},
      {"name": "for", "purpose": "Range-based source: for i in 1 .. 10"}
    ],
    "intermediateOperations": [
      {"name": "filter", "purpose": "Keep items matching predicate (opposite of reject)"},
      {"name": "reject", "purpose": "Remove items matching predicate (opposite of filter)"},
      {"name": "map", "purpose": "Transform each item to a different type"},
      {"name": "sort", "purpose": "Order items using comparison function"},
      {"name": "group", "purpose": "Group into Lists by key function"},
      {"name": "split", "purpose": "Partition into sub-groups by criteria"},
      {"name": "join", "purpose": "Combine two items into one"},
      {"name": "uniq", "purpose": "Remove duplicates (optionally: uniq by key)"},
      {"name": "flatten", "purpose": "Expand nested collections: List of List -> individual items"},
      {"name": "head", "purpose": "Take first N items (replaces break)"},
      {"name": "tail", "purpose": "Take last N items"},
      {"name": "skip", "purpose": "Discard first N items (replaces continue with counter)"},
      {"name": "tee", "purpose": "Side-copy into variable, continue pipeline"},
      {"name": "call", "purpose": "Invoke function delegate on each item"},
      {"name": "async", "purpose": "Invoke function delegate asynchronously"}
    ],
    "terminals": [
      {"name": "> sink", "purpose": "Direct output to collection or Stdout"},
      {"name": ">> collection", "purpose": "Append to existing collection"},
      {"name": "collect as Type", "purpose": "Materialize into new collection"}
    ],
    "replacesImperativePatterns": {
      "break": "head N (stop after N items)",
      "continue": "filter by condition (skip non-matching)",
      "loopWithSet": "uniq (deduplicate without manual tracking)",
      "nestedLoops": "group by key | map with transform | flatten"
    },
    "examples": [
      {
        "description": "Find first match (replaces loop + break)",
        "code": "result <- cat items | filter by matches | head"
      },
      {
        "description": "Skip invalid items (replaces continue)",
        "code": "cat items | filter by isValid | map with transform | collect as List of Output"
      },
      {
        "description": "Sort, group, and process",
        "code": "cat library | sort by comparingAuthor | group by authorId | filter with sufficientBooks | map by orderOnPublishedDate | flatten > stdout"
      },
      {
        "description": "Collect all enum values",
        "code": "allColours <- cat Colour | collect as List of Colour"
      }
    ],
    "documentation": "https://ek9.io/streamsAndPipelines.html"
  },

  "purityRules": {
    "description": "EK9's pragmatic purity model - compile-time enforcement limiting internal state mutation",
    "syntax": "functionName() as pure",
    "clarification": {
      "notHaskellPurity": "EK9 'pure' controls INTERNAL STATE MUTATION, not all side effects like Haskell",
      "ioIsSeparate": "I/O is essential and handled via IO types - not what 'pure' restricts",
      "whatPurePrevents": "Unexpected internal state changes that cause bugs, race conditions, unpredictable behavior",
      "whyPrintlnWorksInPure": "println doesn't mutate program state - it's an external I/O operation, a different concern"
    },
    "whatPureEnforces": {
      "canOnlyCallPureFunctions": "Pure functions/methods can only call other pure functions/methods (transitive)",
      "noDirectReassignment": "Cannot use := or : to reassign variables - only :=? (assign if unset) allowed",
      "cannotModifyParameters": "Cannot reassign or mutate incoming parameters (even :=? not allowed)",
      "cannotMutateFields": "Cannot modify instance fields/properties (except in constructors)",
      "canReadFields": "Can read fields and call pure methods on them"
    },
    "exceptions": {
      "returnVariable": "Return variable (<- rtn) can be assigned multiple times",
      "unsetVariables": "Variables that are UNSET can be assigned with :=?",
      "constructors": "Constructors can initialize fields with :=? (they MUST initialize state)",
      "loopVariables": "System-managed loop variables (for i in ...) are allowed"
    },
    "constructorPurity": {
      "rule": "All constructors in a class must have CONSISTENT purity (all pure or all non-pure)",
      "errorCode": "E50402",
      "pattern": "Use :=? to initialize properties in pure constructors"
    },
    "errorCodes": {
      "E50400": "NONE_PURE_CALL_IN_PURE_SCOPE - calling non-pure from pure context",
      "E50401": "NO_PURE_REASSIGNMENT - direct := assignment in pure context",
      "E50402": "MIX_OF_PURE_AND_NOT_PURE_CONSTRUCTORS - inconsistent constructor purity",
      "E50403": "SUPER_IS_PURE - non-pure function extending pure abstract",
      "E50404": "SUPER_IS_NOT_PURE - pure function extending non-pure abstract",
      "E50405": "NO_INCOMING_ARGUMENT_REASSIGNMENT - modifying incoming parameters"
    },
    "practicalGuidance": {
      "whenToUsePure": "Mark pure if it doesn't mutate any field/property state",
      "benefit": "Pure functions are deterministic, testable, and safe for concurrent execution",
      "pattern": "Use more local variables (like LLVM SSA) instead of reassignment"
    },
    "subtlety": {
      "creatingVsCalling": "Creating a non-pure function in pure context is OK - but CALLING it is NOT",
      "example": "rtn :=? () is SomeNonPureFunction as function ...  // OK - creation is pure\nresult <- rtn(22)  // ERROR - calling non-pure function"
    },
    "documentation": "https://ek9.io/basics.html#pure"
  },

  "sanitizedTypes": {
    "description": "EK9's compile-time security model for input validation - 'Rejection at the Source'",
    "criticalRule": "The 'sanitized' modifier is ONLY valid on String parameters in function/method signatures",
    "philosophy": {
      "name": "Rejection at the Source",
      "meaning": "Sanitize external inputs at system entry points ONLY - once inside trusted boundary, data is clean",
      "benefit": "Security happens at compile-time through parameter declaration, not runtime checks scattered through code"
    },
    "parameterSemantics": {
      "criticalInsight": "Sanitized parameters are effectively PASS-BY-VALUE, not pass-by-reference",
      "explanation": "EK9 normally uses pass-by-reference (changes to parameter affect original). For sanitized parameters, a NEW copy is created (if safe) or an UNSET value is returned (if threat detected). The original is NEVER exposed.",
      "whyNoAliasing": "Because we always create a copy, aliasing the parameter would expose a reference that doesn't represent the sanitization semantics. Direct assignment is blocked to highlight this pass-by-value behavior."
    },
    "whereAllowed": {
      "allowed": ["Function parameters", "Method parameters"],
      "notAllowed": ["Variables declarations", "Return types", "Capture variables", "Call sites"]
    },
    "threatTypes": [
      {"name": "SQL_INJECTION", "severity": 8, "description": "SQL injection patterns"},
      {"name": "SQL_INJECTION_SIGNATURE", "severity": 8, "description": "libinjection-style SQL detection"},
      {"name": "COMMAND_INJECTION", "severity": 9, "description": "Shell/command injection"},
      {"name": "PATH_TRAVERSAL", "severity": 6, "description": "Directory traversal (../)"},
      {"name": "XSS", "severity": 7, "description": "Cross-site scripting"},
      {"name": "XXE", "severity": 8, "description": "XML External Entity"},
      {"name": "SSTI", "severity": 7, "description": "Server-Side Template Injection"}
    ],
    "loggingFormats": {
      "description": "Controlled by EK9_SANITIZER_LOG_FORMAT environment variable",
      "formats": [
        {"name": "JSON", "default": true, "description": "Universal JSON format for any log shipper"},
        {"name": "ECS", "description": "Elastic Common Schema - for Elasticsearch, Splunk, Datadog"},
        {"name": "CEF", "description": "Common Event Format - for ArcSight, Azure Sentinel, QRadar"},
        {"name": "SIMPLE", "description": "Simple bracket format for testing/scripts"},
        {"name": "SILENT", "description": "Suppresses all output - for testing"}
      ]
    },
    "inputSanitizerClass": {
      "description": "Programmatic access to sanitization for manual validation",
      "methods": [
        {"name": "sanitize(input)", "returns": "Safe input or UNSET if threat"},
        {"name": "isSafe(input)", "returns": "Boolean true/false/unset"},
        {"name": "detectThreat(input)", "returns": "Threat type string or UNSET if safe"},
        {"name": "sanitizeWithoutPathChecks(input)", "returns": "For environment variables with legitimate paths"}
      ],
      "customization": "Cannot be directly modified. Companies must extend InputSanitizer and call methods manually."
    },
    "examples": {
      "correct": {
        "functionParameter": "processInput()\n  -> sanitized input as String\n  if input?\n    // Safe to use - guaranteed clean\n    db.query(input)",
        "manualSanitization": "sanitizer <- InputSanitizer()\nif clean <- sanitizer.sanitize(userInput)\n  process(clean)"
      },
      "wrong": {
        "directAssignment": "local <- sanitizedParam  // ERROR: Cannot alias sanitized parameter",
        "variableDeclaration": "sanitized name <- getString()  // ERROR: Not on variables",
        "captureVariable": "sanitized captured as String  // ERROR: Not in captures",
        "callSite": "process(sanitized value)  // ERROR: Not at call site"
      }
    },
    "errorCodes": {
      "E07910": "SANITIZED_ON_ARGUMENT_NOT_SUPPORTED - sanitized used at call site",
      "E07920": "SANITIZED_ONLY_ON_STRING - sanitized on non-String type",
      "E07930": "CANNOT_ASSIGN_FROM_SANITIZED - direct assignment from sanitized parameter (aliasing)",
      "E07940": "SANITIZED_ONLY_IN_DECLARATION - sanitized in wrong context",
      "E07941": "SANITIZED_NOT_ALLOWED_IN_CAPTURE - sanitized on captured variable",
      "E07942": "SANITIZED_NOT_ALLOWED_ON_VARIABLE - sanitized on variable declaration",
      "E07943": "SANITIZED_NOT_ALLOWED_ON_RETURN - sanitized on return type"
    },
    "documentation": "https://ek9.io/sanitized.html"
  },

  "methodResolution": {
    "description": "EK9's cost-based method matching algorithm for overloaded methods",
    "criticalRule": "Methods are overloadable, functions are NOT - function names must be unique per module",
    "costBasedMatching": {
      "description": "Lower cost = better match. Percentage = 100.0 - totalCost",
      "costs": [
        {"name": "ZERO_COST", "value": 0.0, "meaning": "Exact type match - perfect"},
        {"name": "SUPER_COST", "value": 0.05, "meaning": "Match via superclass (per level)"},
        {"name": "TRAIT_COST", "value": 0.10, "meaning": "Match via trait (less specific than superclass)"},
        {"name": "COERCION_COST", "value": 0.5, "meaning": "Type promotion via #^ operator required"},
        {"name": "HIGH_COST", "value": 20.0, "meaning": "Match to 'Any' type - last resort only"},
        {"name": "INVALID_COST", "value": -1.0, "meaning": "No match possible"}
      ],
      "whyTraitCostsMoreThanSuper": "A class can implement many traits but only extends one superclass - superclass relationship is more specific"
    },
    "ambiguityDetection": {
      "description": "Two methods are ambiguous if their percentage match is within 0.001 tolerance",
      "whySmallTolerance": "Cost calculations use multipliers for multiple parameters, creating finer granularity",
      "errorCode": "E06140",
      "example": {
        "methods": "methodA(C1, C2) and methodA(C2, C1)",
        "call": "methodA(c2, c3) where c3 extends C2 extends C1",
        "costA": "c2→C1 (0.05) + c3→C2 (0.05) = 0.10",
        "costB": "c2→C2 (0.0) + c3→C1 (0.10) = 0.10",
        "result": "AMBIGUOUS - both have identical cost"
      }
    },
    "anyTypeHandling": {
      "description": "'Any' is the universal base type - root of EK9's type hierarchy",
      "cost": "HIGH_COST (20.0) - deliberately expensive to ensure specific types always preferred",
      "pattern": "Many built-in types have both specific and Any overloads",
      "example": "_eq(List arg) costs 0.0, _eq(Any arg) costs 20.0 - List version always wins"
    },
    "returnTypeMatching": {
      "description": "Return type compatibility is pass/fail only - no cost impact",
      "rule": "If return type specified in search and incompatible, method is rejected (not cost-adjusted)"
    },
    "noAutomaticPromotions": {
      "criticalRule": "EK9 has NO hidden/automatic type promotions",
      "explanation": "Everything is an object. Integer has explicit #^ promotion operator to Float",
      "benefit": "No surprises - all type conversions are visible in the code"
    },
    "functionResolution": {
      "description": "Functions CANNOT be overloaded - names must be unique per module",
      "errorIfDuplicate": "E02010 (DUPLICATE_NAME)",
      "resolution": "Simple parameter signature validation - no cost-based matching needed"
    },
    "errorCodes": {
      "E06140": "METHOD_AMBIGUOUS - multiple methods match with same cost",
      "E50060": "METHOD_NOT_RESOLVED - no matching method found",
      "E06270": "FUNCTION_PARAMETER_MISMATCH - function called with wrong parameters"
    },
    "documentation": "https://ek9.io/methods.html"
  },

  "operatorSemantics": {
    "description": "EK9 operator behavior - mutating vs non-mutating",
    "criticalWarning": "Mutating operators return 'this' - assignment creates ALIASES, not copies",
    "mutatingOperators": {
      "description": "These operators MUTATE the target and return reference to same object",
      "operators": [
        {"symbol": "++", "method": "_inc", "note": "x++ mutates x AND returns x (not a copy!)"},
        {"symbol": "--", "method": "_dec", "note": "x-- mutates x AND returns x"},
        {"symbol": "+=", "method": "_addAss", "note": "Mutates and returns this"},
        {"symbol": "-=", "method": "_subAss", "note": "Mutates and returns this"},
        {"symbol": "*=", "method": "_mulAss", "note": "Mutates and returns this"},
        {"symbol": "/=", "method": "_divAss", "note": "Mutates and returns this"},
        {"symbol": ":=:", "method": "_copy", "note": "Deep copy INTO target"},
        {"symbol": ":^:", "method": "_replace", "note": "Replace content"},
        {"symbol": ":~:", "method": "_merge", "note": "Merge content"}
      ],
      "aliasingDanger": {
        "example": "x <- Integer(5)\ny <- x++  // y and x are NOW THE SAME OBJECT!\n// x = 6, y = 6 (both reference same Integer)",
        "warning": "This is DIFFERENT from C/C++/Java where y = x++ creates independent copies"
      }
    },
    "nonMutatingOperators": {
      "description": "These operators return NEW objects - safe for functional programming",
      "operators": [
        {"symbol": "+", "method": "_add"},
        {"symbol": "-", "method": "_sub"},
        {"symbol": "*", "method": "_mul"},
        {"symbol": "/", "method": "_div"},
        {"symbol": "- (unary)", "method": "_negate"},
        {"symbol": "abs", "method": "_abs"},
        {"symbol": "==", "method": "_eq"},
        {"symbol": "<>", "method": "_neq"},
        {"symbol": "<", "method": "_lt"},
        {"symbol": ">", "method": "_gt"},
        {"symbol": "<=", "method": "_le"},
        {"symbol": ">=", "method": "_ge"},
        {"symbol": "<=>", "method": "_cmp"}
      ]
    },
    "documentation": "https://ek9.io/operators.html"
  },

  "coalescingOperators": {
    "description": "Operators that gracefully handle tri-state (absent/unset/set)",
    "operators": [
      {
        "symbol": "??",
        "name": "Null Coalescing",
        "meaning": "Return left if SET, otherwise return right",
        "example": "result <- getValue() ?? defaultValue"
      },
      {
        "symbol": "?:",
        "name": "Elvis Operator",
        "meaning": "Return left if SET, otherwise return right (same as ??)",
        "example": "name <- input ?: \"Anonymous\""
      },
      {
        "symbol": ":=?",
        "name": "Guarded Assignment",
        "meaning": "Only assign if target is currently UNSET",
        "example": "config :=? loadDefaults()  // Only loads if config unset"
      },
      {
        "symbol": "?",
        "name": "Is Set Check",
        "meaning": "Returns true if value is SET (has meaningful value)",
        "example": "if name?\n  process(name)"
      }
    ],
    "documentation": "https://ek9.io/operators.html#coalescing"
  },

  "requireAndAssert": {
    "description": "EK9 precondition and assertion mechanisms",
    "require": {
      "purpose": "Verify precondition — throws UNCATCHABLE exception if false (like panic)",
      "syntax": "require expression",
      "examples": [
        "require name?",
        "require age > 0",
        "require firstName? and lastName?",
        "require not true"
      ],
      "semantics": "When require fails, it indicates a serious unrecoverable defect. There is NO recovery — execution terminates. By design, require failures cannot drive control flow.",
      "useCases": [
        "Constructor argument validation: require id?",
        "Method preconditions: require amount > 0",
        "Invariant checking: require balance >= 0",
        "Defensive default constructor blocking: require not true"
      ]
    },
    "assert": {
      "purpose": "Test assertions in @Test programs — throws exception if false",
      "syntax": "assert expression",
      "note": "Use in @Test programs for test validation. Similar to require but specifically for test assertions."
    },
    "documentation": "https://ek9.io/testing.html#require"
  },

  "syntax": {
    "indentation": "2 spaces (not tabs)",
    "noSemicolons": true,
    "noCurlyBraces": true,
    "declaration": "name <- value",
    "typedDeclaration": "name as Type: value",
    "assignment": "name: value",
    "guardAssignment": "name :=? value",
    "comments": {
      "singleLine": "// comment",
      "multiLine": "<?- comment -?>"
    }
  },

  "siteMap": {
    "description": "Complete EK9 documentation site map organized by category",
    "baseUrl": "https://ek9.io/",

    "gettingStarted": {
      "description": "Introduction and basics for new developers",
      "pages": [
        {"url": "index.html", "title": "About EK9", "description": "Overview and philosophy"},
        {"url": "introduction.html", "title": "Introduction", "description": "Getting started guide"},
        {"url": "structure.html", "title": "Structure", "description": "Module structure, indentation syntax"},
        {"url": "basics.html", "title": "Basics", "description": "Variables, types, tri-state semantics"}
      ]
    },

    "coreLanguage": {
      "description": "Core language constructs and syntax",
      "pages": [
        {"url": "operators.html", "title": "Operators", "description": "All EK9 operators including ?. :=?, ==, <=>"},
        {"url": "flowControl.html", "title": "Flow Control", "description": "Guards, conditionals, loops (NO break/continue/return)"},
        {"url": "exceptions.html", "title": "Exceptions", "description": "Error handling with try/catch"},
        {"url": "constants.html", "title": "Constants", "description": "Constant definitions"},
        {"url": "programs.html", "title": "Programs", "description": "Entry points and program structure"}
      ]
    },

    "types": {
      "description": "Type system and built-in types",
      "pages": [
        {"url": "builtInTypes.html", "title": "Built-in Types", "description": "String, Integer, Boolean, etc. (NO null)"},
        {"url": "collectionTypes.html", "title": "Collection Types", "description": "List, Dict, Optional, Result"},
        {"url": "standardTypes.html", "title": "Standard Types", "description": "Date, Time, Duration, etc."},
        {"url": "networkTypes.html", "title": "Network Types", "description": "HTTP, TCP, UDP types"},
        {"url": "sanitized.html", "title": "Input Sanitization", "description": "Sanitized types for security"},
        {"url": "enumerations.html", "title": "Enumerations", "description": "Enum definitions"},
        {"url": "records.html", "title": "Records", "description": "Data-focused aggregates (mutable — immutability via 'pure')"},
        {"url": "generics.html", "title": "Generics/Templates", "description": "Generic type parameters"}
      ]
    },

    "objectOriented": {
      "description": "Object-oriented programming constructs",
      "pages": [
        {"url": "classes.html", "title": "Classes", "description": "Class definitions (closed by default)"},
        {"url": "methods.html", "title": "Methods", "description": "Method definitions and dispatchers"},
        {"url": "traits.html", "title": "Traits", "description": "Interface-like abstractions"},
        {"url": "composition.html", "title": "Composition", "description": "Extension by composition with 'by'"},
        {"url": "inheritance.html", "title": "Inheritance", "description": "Type inheritance (use 'as open')"},
        {"url": "advancedClassMethods.html", "title": "Advanced Methods", "description": "Advanced class method patterns"}
      ]
    },

    "functional": {
      "description": "Functional programming features",
      "pages": [
        {"url": "functions.html", "title": "Functions", "description": "Function definitions (NO return statement)"},
        {"url": "dynamicFunctions.html", "title": "Dynamic Functions", "description": "First-class functions"},
        {"url": "dynamicClasses.html", "title": "Dynamic Classes", "description": "Runtime class creation"},
        {"url": "streamsAndPipelines.html", "title": "Streams/Pipelines", "description": "Stream processing (replaces break/continue)"}
      ]
    },

    "enterprise": {
      "description": "Enterprise and application features",
      "pages": [
        {"url": "components.html", "title": "Components", "description": "Component definitions"},
        {"url": "dependencyInjection.html", "title": "Dependency Injection", "description": "DI patterns"},
        {"url": "webServices.html", "title": "Web Services", "description": "REST services"},
        {"url": "commonDesignPatterns.html", "title": "Design Patterns", "description": "Common EK9 patterns"},
        {"url": "textProperties.html", "title": "Text/Properties", "description": "I18n and configuration"}
      ]
    },

    "tooling": {
      "description": "Development tools and compiler",
      "pages": [
        {"url": "commandline.html", "title": "Command Line", "description": "Compiler options including -E3/-E5 for AI"},
        {"url": "testing.html", "title": "Testing", "description": "Test framework and coverage"},
        {"url": "quality.html", "title": "Code Quality", "description": "Metrics and thresholds"},
        {"url": "packaging.html", "title": "Packaging", "description": "Building and distributing"},
        {"url": "repl.html", "title": "REPL", "description": "Interactive evaluation"}
      ]
    },

    "reference": {
      "description": "Reference documentation",
      "pages": [
        {"url": "errors.html", "title": "Error Index", "description": "All compiler errors with fixes"},
        {"url": "forAI.html", "title": "For AI Assistants", "description": "AI-specific guidance (HTML version)"}
      ]
    }
  },

  "commonAIMistakes": {
    "description": "Frequent mistakes AI assistants make when generating EK9 code",
    "syntaxMistakes": {
      "multipleArrows": {
        "description": "Using multiple -> for multiple parameters",
        "severity": "PARSE_FAILURE",
        "wrong": "myFunc()\n  -> arg1 as String\n  -> arg2 as Integer",
        "correct": "myFunc()\n  ->\n    arg1 as String\n    arg2 as Integer",
        "rule": "Single -> on its own line, then each parameter indented below"
      },
      "curlyBracesForBlocks": {
        "description": "Using {} for code blocks like C/Java",
        "severity": "PARSE_FAILURE",
        "wrong": "if condition { doSomething() }",
        "correct": "if condition\n  doSomething()",
        "rule": "Curly braces {} are ONLY for Dict literals: {1: \"one\", 2: \"two\"}"
      },
      "squareBracketsAsArrays": {
        "description": "Thinking [] creates arrays",
        "severity": "MISCONCEPTION",
        "correct": "[1, 2, 3] creates a List of Integer, NOT an array",
        "rule": "EK9 has no arrays - [] is shorthand for List literals"
      },
      "pythonColonAfterStatements": {
        "description": "Adding : after if/for/while like Python",
        "severity": "PARSE_FAILURE",
        "wrong": "if condition:",
        "correct": "if condition",
        "rule": "No colon after control flow statements - just newline and indent"
      },
      "lambdaSyntax": {
        "description": "Using lambda/arrow function syntax from other languages",
        "severity": "PARSE_FAILURE",
        "wrong": "fn = (x) => x * 2",
        "correct": "fn <- (x) is Transformer as function\n  <- rtn: x * 2",
        "rule": "EK9 uses 'dynamic functions': (captures) is FunctionType as function"
      },
      "cStyleForLoop": {
        "description": "Using C-style for(i=0; i<10; i++)",
        "severity": "PARSE_FAILURE",
        "wrong": "for (i = 0; i < 10; i++)",
        "correct": "for i in 0 ... 10",
        "rule": "Use 'for variable in range' or 'for item in collection'"
      },
      "enumValuesOnOneLine": {
        "description": "Enum values must be one-per-line OR comma-separated — not indented block without commas",
        "severity": "PARSE_FAILURE",
        "wrong": "CardSuit\n    Hearts\n    Diamonds",
        "correct": "CardSuit\n  Hearts\n  Diamonds\n\n// OR comma-separated:\nCardSuit\n  Hearts, Diamonds, Clubs, Spades",
        "rule": "Each enum value on its own line at one indent level deeper than the type name, OR comma-separated on one/multiple lines"
      },
      "catWithRange": {
        "description": "Using 'cat' with a numeric range — 'cat' takes collections or types, not ranges",
        "severity": "PARSE_FAILURE",
        "wrong": "cat 1 ... 10 | map by transform | collect as List of Integer",
        "correct": "for i in 1 ... 10 | map by transform | collect as List of Integer",
        "rule": "'cat' streams from collections (cat myList) or enumeration types (cat Colour). Use 'for i in start ... end' to generate ranges in stream pipelines."
      }
    },
    "semanticMistakes": {
      "usingExcludedKeywords": {
        "description": "Using break, continue, return, null",
        "errorCodes": ["E01070", "E01071", "E01072", "E01073"],
        "rule": "These keywords do not exist - see $.excludedFeatures"
      },
      "instanceofOrCasting": {
        "description": "Trying to check or cast types at runtime",
        "rule": "No instanceof, no casting - use dispatcher pattern only"
      },
      "automaticTypePromotion": {
        "description": "Assuming Integer converts to Float automatically",
        "rule": "All promotions explicit via #^ operator: intVal#^"
      },
      "overloadingFunctions": {
        "description": "Creating multiple functions with same name",
        "errorCode": "E01040",
        "rule": "Functions cannot be overloaded - only methods can"
      },
      "extendingClosedTypes": {
        "description": "Extending List, Dict, Optional, etc.",
        "errorCode": "E05030",
        "rule": "Built-in generic types are closed - use composition"
      },
      "reassigningInPure": {
        "description": "Using := in pure functions",
        "errorCode": "E50401",
        "rule": "Only :=? (assign if unset) allowed in pure contexts"
      },
      "aliasingSanitized": {
        "description": "Direct assignment from sanitized parameter",
        "errorCode": "E07930",
        "rule": "Cannot alias sanitized params - pass-by-value semantics"
      },
      "incrementInExpression": {
        "description": "Using x++ in expressions like y <- x++",
        "errorCode": "E07950",
        "rule": "++/-- are statement-only, not expression operators"
      },
      "manualJsonSerialization": {
        "description": "Writing custom JSON conversion instead of using default operator $$",
        "rule": "Use 'default operator $$' on records/classes for auto-generated JSON. List of T also has $$ operator.",
        "example": {
          "wrong": "toJSON()\n  -> c as Customer\n  <- rtn as String: `{ \"name\": \"${c.name}\" }`",
          "correct": "Customer\n  name as String\n  default operator $$\n//Usage: json <- $$customer"
        }
      },
      "manualStringSerialization": {
        "description": "Writing custom String conversion instead of using default operator $",
        "rule": "Use 'default operator $' for auto-generated string representation",
        "example": {
          "wrong": "toString()\n  -> c as Customer\n  <- rtn as String: c.name + \" \" + c.surname",
          "correct": "Customer\n  name as String\n  surname as String\n  default operator $\n//Usage: str <- $customer"
        }
      },
      "unusedTraitDefinition": {
        "description": "Defining a trait but implementing its operations as standalone functions instead of a class",
        "rule": "If you define a trait, always implement it with 'class X with trait of TraitName'. Never define a trait and then ignore it.",
        "severity": "DESIGN_FLAW"
      },
      "unusedParameter": {
        "description": "Declaring a parameter that is never referenced in the function/method body",
        "errorCode": "E08091",
        "rule": "Every declared parameter must be used. Remove unused parameters or use them in the body.",
        "exemptions": [
          "Abstract methods/functions (no body)",
          "Override methods (signature forced by parent)",
          "Dispatcher methods (must accept dispatched type)",
          "Operators (fixed semantics)",
          "Functions explicitly extending another function",
          "Methods on parameterised types (signature forced by generic contract)"
        ],
        "severity": "COMPILE_ERROR"
      },
      "operatorQuestionMustBePure": {
        "description": "operator ? must ALWAYS be declared 'as pure' — it is a query, never mutates",
        "errorCode": "E07500",
        "wrong": "override operator ?\n  <- rtn as Boolean: name?",
        "correct": "override operator ? as pure\n  <- rtn as Boolean: name?",
        "rule": "operator ? checks if a value is set — this is inherently pure. The compiler requires 'as pure' on every ? operator declaration.",
        "severity": "COMPILE_ERROR"
      },
      "enumSwitchExhaustivenessAndDefault": {
        "description": "Switch expression on enum requires BOTH all enum cases AND a default clause",
        "errorCodes": ["E07310", "E07330"],
        "wrong": "switch status\n  <- rtn as String?\n  case Status.Active\n    rtn: \"active\"\n  default\n    rtn: \"other\"",
        "correct": "switch status\n  <- rtn as String?\n  case Status.Active\n    rtn: \"active\"\n  case Status.Inactive\n    rtn: \"inactive\"\n  default\n    rtn: \"unknown\"",
        "rule": "When switching on an enumeration as an EXPRESSION (<- rtn), list ALL enum values explicitly AND include a default. E07310 fires if cases are missing, E07330 fires if default is missing.",
        "severity": "COMPILE_ERROR"
      },
      "copyConstructorInPureContext": {
        "description": "Calling a copy constructor like TypeName(existingVar) inside a pure method when the constructor is not pure",
        "errorCode": "E08130",
        "wrong": "status() as pure\n  <- rtn as ConnectionStatus: ConnectionStatus(currentStatus)",
        "correct": "status()\n  <- rtn as ConnectionStatus: ConnectionStatus(currentStatus)\n\n// OR if method must be pure, return the field directly if semantics allow it",
        "rule": "Copy constructors may not be marked pure. If you need to return a copy from a pure method, either remove 'as pure' from the method, or find a pure alternative. Use 'ek9 -h <Type>' to check if the copy constructor is pure.",
        "severity": "COMPILE_ERROR"
      }
    },
    "assignmentConfusion": {
      "description": "EK9 has multiple assignment forms",
      "forms": [
        {"syntax": "name <- value", "meaning": "Declaration with type INFERENCE (most common)"},
        {"syntax": "name as Type: value", "meaning": "Declaration with EXPLICIT type, assign with :"},
        {"syntax": "name as Type := value", "meaning": "Declaration with EXPLICIT type, assign with :="},
        {"syntax": "name: value", "meaning": "REASSIGNMENT to existing variable"},
        {"syntax": "name := value", "meaning": "REASSIGNMENT to existing variable"},
        {"syntax": "name :=? value", "meaning": "Assign ONLY if currently unset"}
      ],
      "keyPoint": "<- is NOT the only way to declare - it's just the type-inference form"
    }
  },

  "errorCodeIndex": {
    "description": "Lookup from error code to forAI.json path — AI assistants use this to find structured guidance for any compiler error",

    "E01070": "excludedFeatures.break",
    "E01071": "excludedFeatures.continue",
    "E01072": "excludedFeatures.return",
    "E01073": "excludedFeatures.null",
    "E01074": "excludedFeatures.semicolon",
    "E01075": "excludedFeatures.new",
    "E01076": "excludedFeatures.goto",
    "E01077": "excludedFeatures.def",
    "E01078": "excludedFeatures.elif",
    "E01079": "excludedFeatures.None",
    "E01080": "excludedFeatures.self",
    "E01081": "excludedFeatures.listComprehension",
    "E01082": "excludedFeatures.multipleArgumentArrows",
    "E01083": "excludedFeatures.multipleReturnArrows",

    "E05030": "closedByDefault",

    "E11010": "qualityMetrics.cyclomaticComplexity",
    "E11021": "qualityMetrics.cognitiveComplexity",
    "E11011": "qualityMetrics.nestingDepth",
    "E11012": "qualityMetrics.statementCount",
    "E11014": "qualityMetrics.cohesion",
    "E11015": "qualityMetrics.coupling",
    "E11019": "qualityMetrics.inheritanceDepth",

    "E11031": "bannedIdentifiers",

    "E50400": "purityRules",
    "E50401": "purityRules",
    "E50402": "purityRules",
    "E50403": "purityRules",
    "E50404": "purityRules",
    "E50405": "purityRules",

    "E07910": "sanitizedTypes",
    "E07920": "sanitizedTypes",
    "E07930": "sanitizedTypes",
    "E07940": "sanitizedTypes",
    "E07941": "sanitizedTypes",
    "E07942": "sanitizedTypes",
    "E07943": "sanitizedTypes",

    "E06140": "methodResolution",
    "E50060": "methodResolution",
    "E06270": "methodResolution",

    "E01040": "commonAIMistakes.semanticMistakes.overloadingFunctions",
    "E07950": "commonAIMistakes.semanticMistakes.incrementInExpression",
    "E08091": "commonAIMistakes.semanticMistakes.unusedParameter",

    "E07120": "dispatcherPattern",
    "E07820": "dispatcherPattern",
    "E05170": "dispatcherPattern",
    "E05180": "dispatcherPattern",

    "E06180": "accessModifiers",

    "E07310": "commonAIMistakes.semanticMistakes.enumSwitchExhaustivenessAndDefault",
    "E07330": "commonAIMistakes.semanticMistakes.enumSwitchExhaustivenessAndDefault",
    "E07500": "commonAIMistakes.semanticMistakes.operatorQuestionMustBePure",
    "E08130": "commonAIMistakes.semanticMistakes.copyConstructorInPureContext",

    "E08080": "codeQualityEnforcement.tautologicalExpressions",
    "E08081": "codeQualityEnforcement.tautologicalExpressions",
    "E08082": "codeQualityEnforcement.tautologicalExpressions",
    "E08083": "codeQualityEnforcement.tautologicalExpressions",
    "E08084": "codeQualityEnforcement.tautologicalExpressions",
    "E08085": "codeQualityEnforcement.tautologicalExpressions",

    "E11018": "codeQualityEnforcement.unusedCaptureDetection",
    "E11022": "codeQualityEnforcement.classDesignAntiPatterns",
    "E11023": "codeQualityEnforcement.classDesignAntiPatterns",
    "E11024": "codeQualityEnforcement.classDesignAntiPatterns",
    "E11025": "codeQualityEnforcement.classDesignAntiPatterns",
    "E11026": "codeQualityEnforcement.referenceOrdering",
    "E11030": "codeQualityEnforcement.confusinglySimilarNames",
    "E11032": "codeQualityEnforcement.operatorKeywordShadowing",
    "E11040": "codeQualityEnforcement.diInjectionLimits",
    "E11041": "codeQualityEnforcement.diInjectionLimits",
    "E11042": "codeQualityEnforcement.diInjectionLimits",
    "E11043": "codeQualityEnforcement.diInjectionLimits",
    "E11050": "codeQualityEnforcement.discardedReturnValues",
    "E11051": "codeQualityEnforcement.discardedReturnValues",
    "E11052": "codeQualityEnforcement.discardedReturnValues",
    "E11053": "codeQualityEnforcement.dataClumpDetection",
    "E11054": "codeQualityEnforcement.typeTraversalLimit",
    "E11061": "codeQualityEnforcement.namedArgumentEnforcement",
    "E11062": "codeQualityEnforcement.namedArgumentEnforcement",
    "E11064": "codeQualityEnforcement.magicLiteralDetection",
    "E11065": "codeQualityEnforcement.magicLiteralDetection",
    "E11066": "codeQualityEnforcement.constantOrganization",
    "E11067": "codeQualityEnforcement.constantOrganization",
    "E11068": "codeQualityEnforcement.stringInterpolationMandate"
  },

  "aiQuickReference": {
    "description": "Most commonly needed pages for AI assistants",
    "forErrors": "https://ek9.io/errors.html",
    "forQualityIssues": "https://ek9.io/quality.html",
    "forFlowControl": "https://ek9.io/flowControl.html",
    "forStreams": "https://ek9.io/streamsAndPipelines.html",
    "forTypes": "https://ek9.io/builtInTypes.html",
    "forTesting": "https://ek9.io/testing.html",
    "forCommands": "https://ek9.io/commandline.html",
    "forPackaging": "https://ek9.io/packaging.html",
    "forDependencies": "https://ek9.io/packaging.html#dependencies",
    "forComprehensiveGuide": "https://ek9.io/forAI.html"
  },

  "oracleKnowledgeBase": {
    "description": "The EK9 Oracle is an in-process knowledge base of compiler-validated Q&A entries with working code snippets. Both frontier and local LLMs MUST consult the Oracle before writing code.",
    "whatItContains": {
      "qaEntries": "565+ Q&A entries across 49 categories (growing toward 2000+)",
      "codeSnippets": "Every Q&A contains working EK9 code that compiles against the current compiler",
      "migrationContext": "Language comparison notes for developers coming from Java, Python, C#, etc.",
      "errorPatterns": "Common mistakes with error codes and corrected examples"
    },
    "howToQuery": {
      "byKeywords": "ek9 -q <words> — BM25F-ranked search across questions, answers, keywords",
      "byId": "ek9 -q <number> — fetch specific Q&A by ID (e.g., ek9 -q 45)",
      "withMigration": "ek9 -qm <words> — includes language comparison context in results",
      "byProtocol": "ek9 -qp <words> — search protocol-specific Q&A entries for agent coordination",
      "listAll": "ek9 -q — list all categories and entry counts"
    },
    "oracleFirstWorkflow": {
      "description": "The Oracle enables a design-first workflow that inverts the industry-standard generate-then-fix cycle",
      "steps": [
        "DECOMPOSE: Break the user's request into design components (file I/O, validation, DI, etc.)",
        "CONSULT: Query the Oracle for each component — ask-oracle returns proven, compiled snippets",
        "ASSESS: Check coverage — if all components have snippets, proceed. If gaps exist, report them",
        "COMPOSE: Assemble the solution from Oracle snippets, adapting to the specific requirement",
        "VERIFY: Compile and expect near-clean result (1-2 fix cycles, not 8)"
      ],
      "whyThisWorks": "Oracle snippets are compiler-validated against the current compiler version. Starting from proven patterns means the first attempt is usually correct. Code-first approaches that guess from general training data take 5-8x more compile cycles.",
      "tokenSavings": "An Oracle-first approach that starts from snippets needs 1-2 compile cycles. A code-first approach needs 8. Over a session with 10 tasks, that is 15 compile cycles vs 80."
    },
    "criticalRule": "ALWAYS consult the Oracle before writing EK9 code. The Oracle contains patterns that are guaranteed to compile. Generating from general training data wastes tokens on doomed implementations."
  },

  "aiAgentArchitecture": {
    "description": "When running inside ek9 -ai, LLMs operate in a two-tier system with structured delegation and escalation protocols",
    "twoTierModel": {
      "frontier": "Cloud LLM (e.g., Claude) — handles architectural reasoning, complex multi-file analysis, design decisions",
      "local": "Local LLM (e.g., Qwen2.5-Coder-32B) — handles routine compile-fix loops, Oracle consultation, symbol lookups, test execution",
      "ratio": "70-80% of work is handled locally (zero token cost), 20-30% by frontier (targeted, high-value reasoning)"
    },
    "threeMessageTypes": {
      "delegation": {
        "direction": "Frontier -> Local",
        "purpose": "Assign a scoped task (investigation, implementation, or validation)",
        "keyFields": ["taskId", "delegationType", "objective", "questions/instructions", "constraints.responseBudget", "terrainBrief"],
        "protocolQuery": "ek9 -qp delegation brief format"
      },
      "escalation": {
        "direction": "Local -> Frontier",
        "purpose": "Request help when stuck (repeated failure, low confidence, out of scope, oracle gap)",
        "keyFields": ["taskId", "originalObjective", "escalationReason", "currentState", "attemptHistory", "specificQuestion"],
        "criticalRule": "Escalation requests must be self-contained — the frontier should be able to help without re-investigating",
        "protocolQuery": "ek9 -qp escalation request format"
      },
      "progress": {
        "direction": "Local -> Frontier (fire-and-forget)",
        "purpose": "Lightweight status update during long delegations (under 100 tokens)",
        "keyFields": ["taskId", "progress.phase", "confidence", "estimatedCompletionSeconds"],
        "protocolQuery": "ek9 -qp progress update format"
      }
    },
    "intentVocabulary": {
      "description": "Local agents express actions as intents — the in-process infrastructure resolves them against the symbol table, Oracle, and compiler APIs. Never generate shell commands.",
      "coreIntents": ["compile", "read-file", "write-file", "edit-file", "search", "ask-oracle", "type-help", "run-tests"],
      "discoveryIntents": ["find-definition", "find-references", "list-methods", "list-operators", "list-constructors", "list-properties", "get-type", "get-signature", "type-hierarchy", "find-implementations", "list-subtypes", "list-module-symbols", "list-modules", "method-resolution"],
      "criticalRule": "Discovery intents resolve from the in-process symbol table in ~0.01ms with zero I/O. ALWAYS prefer discovery intents over search for structural queries (finding definitions, listing methods, tracing hierarchies). The symbol table has this information indexed and typed — it cannot produce false positives.",
      "protocolQuery": "ek9 -qp intent vocabulary"
    }
  },

  "bootstrapSequence": {
    "description": "What both frontier and local LLMs should do when starting an ek9 -ai session",
    "steps": [
      {
        "step": 1,
        "action": "Load this forAI.json reference",
        "purpose": "Understand EK9's excluded features, tri-state semantics, closed types, quality metrics, and operator semantics"
      },
      {
        "step": 2,
        "action": "Know the Oracle exists and how to query it",
        "purpose": "565+ Q&A entries with compiler-validated code snippets are available via ask-oracle intent or ek9 -q. Always consult before coding."
      },
      {
        "step": 3,
        "action": "Know the intent vocabulary",
        "purpose": "22 intents available — 8 core + 14 discovery. Discovery intents use the in-process symbol table (~0.01ms). Never fork to shell for structural queries."
      },
      {
        "step": 4,
        "action": "Know the delegation protocol",
        "purpose": "Frontier delegates via structured briefs, local agents respond with compressed findings. Escalation when stuck. Protocol Q&A available via ek9 -qp."
      },
      {
        "step": 5,
        "action": "Know the compiler is in-process",
        "purpose": "Compilation is a Java method call (~80ms), not fork+exec (~2000ms). The JVM is warm, bootstrap is cached. Re-compile freely — it costs nothing."
      }
    ],
    "forFrontierLLM": "You coordinate. Delegate investigation and routine implementation to local agents. Retain architectural reasoning and novel design. Set terrain context in delegation briefs.",
    "forLocalLLM": "You execute. Consult the Oracle before coding. Use discovery intents for structural queries. Stay within response budgets. Escalate when stuck — do not guess.",
    "inProcessAdvantage": "The EK9 compiler runs in the same JVM. Symbol table queries cost ~0.01ms. Oracle queries cost ~3ms. Compilation costs ~80ms. There is no fork/exec, no JVM cold start, no stderr parsing. Everything is structured JSON from typed APIs."
  },

  "aiWorkflowGuidance": {
    "description": "Guidance for AI assistants to produce better EK9 code",
    "planFirst": {
      "description": "Always create a plan before writing EK9 code",
      "rule": "Present the plan to the user and ask for feedback before implementing",
      "questionsToAsk": [
        "Do you want standalone functions, or a trait/class design with operators?",
        "Should I use 'default operator' for auto-generated $, $$, :=:, ==, <=> operators?",
        "Do you need a component/application (DI) architecture, or a simpler program?",
        "Should records use 'default operator $$' for JSON serialization?"
      ]
    },
    "designPatternSelection": {
      "description": "Choose the right EK9 pattern for the task",
      "patterns": [
        {
          "name": "Functions only",
          "when": "Simple utilities, stateless transformations, scripts",
          "example": "String formatting, math operations, data transformation"
        },
        {
          "name": "Trait + Class",
          "when": "CRUD operations, stateful services, polymorphic behavior",
          "example": "Database access, customer management, repository pattern",
          "rule": "If you define a trait, you MUST implement it with a class - never abandon a trait for standalone functions"
        },
        {
          "name": "Component + Application",
          "when": "Dependency injection, service wiring, enterprise architecture",
          "example": "Web applications, microservices, multi-component systems"
        },
        {
          "name": "Record + default operators",
          "when": "Data transfer objects, API responses, configuration, value objects",
          "example": "Customer record, OrderLine, Config",
          "rule": "Always consider 'default operator $$' for JSON and 'default operator $' for string display"
        }
      ]
    },
    "operatorAwareness": {
      "description": "EK9 records and classes can have operators - don't write functions for what operators provide",
      "criticalRule": "Before writing a function that converts to JSON or String, check if 'default operator $$' or 'default operator $' already does this",
      "autoGeneratedOperators": {
        "$$": "JSON serialization - produces JSON for all fields automatically",
        "$": "String representation - produces display string for all fields",
        "?": "isSet check - returns true if ANY field is set",
        ":=:": "Deep copy - copies all fields",
        "==": "Equality comparison",
        "<=>": "Three-way comparison",
        "#?": "Hash code"
      },
      "example": {
        "wrong": "customerToJSON()\n  -> c as Customer\n  <- rtn as String: `{ \"name\": \"${c.name}\" }`",
        "correct": "//On the Customer record, add:\n  default operator $$\n//Then use: $$customer or $$(listOfCustomers)"
      }
    },
    "traitImplementation": {
      "description": "Traits define interfaces - they must be implemented",
      "criticalRule": "If you define a trait, you MUST create a class 'with trait of' that implements it. Never define a trait and then use standalone functions instead.",
      "example": {
        "wrong": "defines trait\n  CustomerAccess\n    operator +=\n      -> customer as Customer\n\ndefines function\n  addCustomer()  //WRONG: standalone function instead of trait impl\n    -> customers as List of Customer\n    -> customer as Customer",
        "correct": "defines trait\n  CustomerAccess\n    operator +=\n      -> customer as Customer\n\ndefines class\n  CustomerStore with trait of CustomerAccess\n    customers as List of Customer\n    override operator +=\n      -> customer as Customer\n      customers += customer"
      }
    },
    "proactiveDiWorkflow": {
      "description": "Before adding or modifying dependency injection, inspect the current DI landscape to avoid compile errors",
      "when": "Any task involving: adding injection fields, registering components, wiring applications, adding aspects",
      "steps": [
        {
          "step": 1,
          "action": "Run 'ek9 -di -E3 main.ek9' to see the current wiring map",
          "purpose": "Understand existing registrations, their order, injection sites, and aspect proxies"
        },
        {
          "step": 2,
          "action": "Check if an application block exists",
          "purpose": "If no application exists, you must create one — adding injection fields alone will fail"
        },
        {
          "step": 3,
          "action": "Count existing injection fields on the target component",
          "purpose": "Components with 5+ injection fields trigger E11040 (excessive coupling) — use a facade instead"
        },
        {
          "step": 4,
          "action": "Identify where to insert new registrations in the ordering",
          "purpose": "Dependencies must be registered BEFORE dependents — E08200 fires if order is wrong"
        },
        {
          "step": 5,
          "action": "Add 'default operator ?' to any component with fields",
          "purpose": "Components with properties require operator ? for set/unset semantics — E07235 fires if missing"
        }
      ],
      "commonErrors": {
        "E07235": "Component has fields but no 'default operator ?' — add it after methods",
        "E07236": "Dynamic class captures variables as fields — add 'default operator ?' at end of body",
        "E08190": "Circular dependency — extract shared logic into a third component",
        "E08200": "Registration ordering — reorder so dependencies come first",
        "E08210": "Missing registration — add registration for the injected abstract type",
        "E11040": "Too many injection fields — split into smaller components or use a facade"
      },
      "errorLookup": "Use 'ek9 -h Exxxx' for full diagnosis, fix actions, and examples for any error code"
    },
    "errorDiagnosis": {
      "description": "When a compiler error occurs, use the built-in tools to understand and fix it",
      "steps": [
        "Read the error code (e.g., E50001) from the compiler output",
        "Run 'ek9 -h E50001' for full diagnosis with fix actions and examples",
        "For DI-related errors (E08xxx, E11xxx), also run 'ek9 -di -E3' for the wiring map",
        "Use 'ek9 -q <description>' to find related Q&A entries"
      ],
      "aiNote": "The 'ek9 -h Exxxx' output is structured as [DIAGNOSIS], [ACTION], [SEE ALSO] — designed for AI parsing"
    }
  },

  "inlineExamples": {
    "description": "Self-contained EK9 code examples for AI bootstrapping. These examples are complete and verified to compile.",
    "usage": "AI assistants can use these examples directly to understand EK9 syntax and patterns without external file access.",
    "reminder": "Use 'ek9 -h <keyword>' for help on topics, 'ek9 -h Exxxx' for error diagnosis, 'ek9 -di -E3' for DI wiring map, 'ek9 -q <words>' for Q&A lookup.",

    "helloWorld": {
      "pattern": "basic-program-structure",
      "description": "The canonical Hello World - minimal EK9 program structure",
      "keywords": ["program", "module", "stdout", "println", "<-"],
      "code": "#!ek9\ndefines module introduction\n\n  defines program\n\n    HelloWorld()\n      //Stdout is a built-in type - no import required\n      //The <- operator: declares 'stdout' AND assigns the new Stdout instance\n      //Type inference: compiler knows stdout is type Stdout\n      stdout <- Stdout()\n      stdout.println(\"Hello, World\")\n\n//EOF"
    },

    "simpleFunction": {
      "pattern": "function-with-parameters",
      "description": "Function with parameters and return value - shows -> for input, <- for output",
      "keywords": ["function", "->", "<-", "pure"],
      "code": "#!ek9\ndefines module example.functions\n\n  defines function\n\n    //Single parameter, single return\n    greet() as pure\n      -> name as String\n      <- message as String: \"Hello, \" + name\n\n    //Multiple parameters - use indented block after single ->\n    add() as pure\n      ->\n        a as Integer\n        b as Integer\n      <- result as Integer: a + b\n\n  defines program\n\n    Demo()\n      stdout <- Stdout()\n      stdout.println(greet(\"World\"))\n      stdout.println(`Sum: ${add(2, 3)}`)\n\n//EOF"
    },

    "simpleClass": {
      "pattern": "basic-class-structure",
      "description": "Class with properties, constructor, methods, and operator overloading",
      "keywords": ["class", "method", "property", "operator", "$"],
      "code": "#!ek9\ndefines module example.classes\n\n  defines class\n\n    Person\n      //Properties are always private\n      firstName <- String()\n      lastName <- String()\n\n      //Constructor\n      Person()\n        ->\n          firstName as String\n          lastName as String\n        this.firstName :=: firstName\n        this.lastName :=: lastName\n\n      //Method\n      fullName() as pure\n        <- rtn as String: firstName + \" \" + lastName\n\n      //Operator $ for string conversion\n      operator $ as pure\n        <- rtn as String: fullName()\n\n      //Operator ? for isSet check\n      default operator ?\n\n  defines program\n\n    Demo()\n      stdout <- Stdout()\n      person <- Person(\"Steve\", \"Limb\")\n      stdout.println($person)\n\n//EOF"
    },

    "classExtension": {
      "pattern": "class-extension-hierarchy",
      "description": "Abstract and open classes - EK9 types are closed by default",
      "keywords": ["extends", "override", "abstract", "open"],
      "code": "#!ek9\ndefines module example.inheritance\n\n  defines class\n\n    //Abstract classes are automatically open\n    Shape as abstract\n      name as String?\n\n      Shape()\n        -> name as String\n        this.name :=? name\n\n      area() as pure abstract\n        <- rtn as Float?\n\n      operator $ as pure\n        <- rtn as String: name ?: \"Unknown\"\n\n    //Concrete class extending abstract - closed by default\n    Circle extends Shape\n      radius <- Float()\n\n      Circle()\n        -> radius as Float\n        super(\"Circle\")\n        this.radius :=? radius\n\n      override area() as pure\n        <- rtn as Float: 3.14159 * radius * radius\n\n    //Concrete but marked 'as open' for extension\n    Rectangle extends Shape as open\n      width <- Float()\n      height <- Float()\n\n      Rectangle()\n        ->\n          width as Float\n          height as Float\n        super(\"Rectangle\")\n        this.width :=? width\n        this.height :=? height\n\n      override area() as pure\n        <- rtn as Float: width * height\n\n    //Can extend Rectangle because it's 'as open'\n    Square extends Rectangle\n      Square()\n        -> side as Float\n        super(side, side)\n\n  defines program\n\n    Demo()\n      stdout <- Stdout()\n      shapes <- [Circle(5.0), Rectangle(4.0, 3.0), Square(2.0)]\n      for shape in shapes\n        stdout.println(`${shape}: area = ${shape.area()}`)\n\n//EOF"
    },

    "abstractFunction": {
      "pattern": "abstract-function-polymorphism",
      "description": "Abstract functions as interfaces for polymorphic behavior",
      "keywords": ["function", "abstract", "pure", "is"],
      "code": "#!ek9\ndefines module example.polymorphism\n\n  defines function\n\n    //Abstract function - defines interface\n    mathOperation() as pure abstract\n      ->\n        x as Float\n        y as Float\n      <- result as Float?\n\n    //Concrete implementations\n    add() is mathOperation as pure\n      ->\n        x as Float\n        y as Float\n      <- result as Float: x + y\n\n    subtract() is mathOperation as pure\n      ->\n        x as Float\n        y as Float\n      <- result as Float: x - y\n\n    multiply() is mathOperation as pure\n      ->\n        x as Float\n        y as Float\n      <- result as Float: x * y\n\n  defines program\n\n    Demo()\n      stdout <- Stdout()\n      //Functions can be stored and called polymorphically\n      for op in [add, subtract, multiply]\n        stdout.println(`Result: ${op(10.0, 5.0)}`)\n\n//EOF"
    },

    "traitComposition": {
      "pattern": "trait-with-delegation",
      "description": "Traits for composition, delegation with 'by', and 'allow only' restriction",
      "keywords": ["trait", "with", "by", "delegate", "allow only"],
      "code": "#!ek9\ndefines module example.traits\n\n  defines trait\n\n    //Simple trait\n    Printable\n      print() abstract\n        <- rtn as String?\n\n    //Trait inheriting from another\n    Loggable with trait of Printable\n      log() abstract\n        <- rtn as String?\n\n    //Trait with 'allow only' restriction\n    SecureData allow only EncryptedMessage, SignedMessage\n      data() abstract\n        <- rtn as String?\n\n  defines class\n\n    //Class implementing trait\n    Message with trait of Printable\n      content <- String()\n\n      Message()\n        -> content as String\n        this.content :=? content\n\n      override print()\n        <- rtn as String: content\n\n    //Only these can implement SecureData\n    EncryptedMessage with trait of SecureData\n      override data()\n        <- rtn as String: \"[encrypted]\"\n\n    SignedMessage with trait of SecureData\n      override data()\n        <- rtn as String: \"[signed]\"\n\n    //Delegation with 'by'\n    LoggingMessage with trait of Loggable by printer\n      printer as Printable: Message(\"default\")\n\n      LoggingMessage()\n        -> printer as Printable\n        this.printer :=? printer\n\n      override log()\n        <- rtn as String: `[LOG] ${print()}`\n\n  defines program\n\n    Demo()\n      stdout <- Stdout()\n      msg <- LoggingMessage(Message(\"Hello\"))\n      stdout.println(msg.log())\n\n//EOF"
    },

    "enumeration": {
      "pattern": "enumeration-with-operators",
      "description": "Enumerations with built-in operators, iteration, and switch integration. CRITICAL: Enumerations automatically get 24 operators from a simple value list declaration - no 'default operator' directives needed. Do NOT write comparison, conversion, lookup, or serialization functions for enumerations - they are all built-in.",
      "keywords": ["type", "enum", "for", "switch", "cat"],
      "aiWarning": "EK9 enumerations are NOT like Java/Python/C# enums. From just a value list (e.g., Colour with Red, Green, Blue), you get 24 operators automatically. Do NOT write: compareEnums() (use < > <= >= <=>), enumToString() (use $), enumToJson() (use $$), findByName() (use Colour(name)), getFirst/getLast() (use #< #>), isValid() (use Colour(name)?), getAllValues() (use cat Colour | collect). ALL of these are built-in.",
      "automaticOperators": {
        "sameTypeComparison": {
          "operators": ["==", "<>", "<", ">", "<=", ">=", "<=>"],
          "description": "Compare two enum values by declaration order (ordinal). Red < Blue is true if Red declared before Blue.",
          "count": 7
        },
        "stringParamComparison": {
          "operators": ["==", "<>", "<", ">", "<=", ">=", "<=>"],
          "description": "Compare enum to a String directly. colour == \"Red\" works without conversion.",
          "count": 7
        },
        "stringConversion": {
          "operators": ["$", "#^"],
          "description": "$ returns the value name as String. #^ promotes to String (same result for enums).",
          "count": 2
        },
        "jsonSerialization": {
          "operators": ["$$"],
          "description": "$$ returns JSON representation of the enum value name.",
          "count": 1
        },
        "hashCode": {
          "operators": ["#?"],
          "description": "Ordinal-based hash code, suitable for Dict keys.",
          "count": 1
        },
        "isSet": {
          "operators": ["?"],
          "description": "Tri-state check. Colour() is unset, Colour.Red is set.",
          "count": 1
        },
        "firstLast": {
          "operators": ["#<", "#>"],
          "description": "#< returns first declared value, #> returns last declared value.",
          "count": 2
        },
        "constructors": {
          "signatures": ["Colour()", "Colour(Colour)", "Colour(String)"],
          "description": "Default (creates unset), copy, and construct-from-string (unset if no match).",
          "count": 3
        },
        "totalAutoGenerated": 24
      },
      "code": "#!ek9\ndefines module example.enumerations\n\n  defines type\n\n    CardSuit\n      Hearts\n      Diamonds\n      Clubs\n      Spades\n\n    CardRank\n      Two, Three, Four, Five, Six, Seven, Eight, Nine, Ten\n      Jack, Queen, King, Ace\n\n  defines program\n\n    Demo()\n      stdout <- Stdout()\n\n      //Access enum values\n      hearts <- CardSuit.Hearts\n      clubs <- CardSuit.Clubs\n\n      //Comparison operators - ALL built-in, do NOT write comparison functions\n      stdout.println(`hearts < clubs: ${hearts < clubs}`)\n      stdout.println(`hearts == clubs: ${hearts == clubs}`)\n      stdout.println(`hearts <=> clubs: ${hearts <=> clubs}`)\n\n      //String-param comparison - compare directly to String\n      stdout.println(`hearts == Hearts: ${hearts == \"Hearts\"}`)\n\n      //String conversion ($) and JSON ($$) - do NOT write toString/toJson\n      stdout.println(`Suit: ${$hearts}`)\n      stdout.println(`JSON: ${$$hearts}`)\n\n      //Hash code (#?) - do NOT write hashCode functions\n      stdout.println(`Hash: ${#?hearts}`)\n\n      //First (#<) and Last (#>) - do NOT write getFirst/getLast\n      stdout.println(`First: ${#< CardSuit}`)\n      stdout.println(`Last: ${#> CardSuit}`)\n\n      //Construct from string - do NOT write findByName functions\n      validSuit <- CardSuit(\"Clubs\")\n      require validSuit?\n\n      invalidSuit <- CardSuit(\"Invalid\")\n      require ~invalidSuit?\n\n      //Is-set check - do NOT write isValid functions\n      require hearts?\n      unknownSuit <- CardSuit()\n      require ~unknownSuit?\n\n      //Iterate all enum values - do NOT write getAllValues\n      stdout.println(\"All suits:\")\n      for suit in CardSuit\n        stdout.println($suit)\n\n      //Switch on enum\n      for rank in CardRank\n        message <- switch rank\n          <- rtn as String?\n          case CardRank.Ace\n            rtn: `Wow, an ${rank}!`\n          case > CardRank.Ten\n            rtn: `Face card: ${rank}`\n          default\n            rtn: `Number: ${rank}`\n        stdout.println(message)\n\n      //Stream pipeline with enum\n      suits <- cat CardSuit | collect as List of CardSuit\n      require suits?\n\n//EOF"
    },

    "constants": {
      "pattern": "constant-declarations",
      "description": "Native literal types for constants - all built-in types supported",
      "keywords": ["constant", "literal", "Integer", "Float", "Duration", "Date"],
      "code": "#!ek9\ndefines module example.constants\n\n  defines constant\n\n    //Boolean literals\n    limitRetries <- true\n    updateLog <- false\n\n    //Character and String\n    delimiter <- ':'\n    author <- \"Steve Limb\"\n\n    //Numbers\n    maxRetries <- 10\n    minTemp <- -2\n    Pi <- 3.14159\n    bitMask <- 0b01110001\n\n    //Time literals\n    noon <- 12:00\n    justAfterNoon <- 12:00:01\n\n    //Duration literals (ISO 8601)\n    maxDuration <- P3Y2M6DT12H15M6S\n    twoYears <- P2Y\n    twoHours <- PT2H\n    timeout <- 250ms\n\n    //Date and DateTime\n    millennium <- 2000-01-01\n    created <- 2018-01-31T01:30:00-05:00\n\n    //Money and Colour\n    maxPayment <- 300000#USD\n    defaultColour <- #AB6F2B\n\n    //Dimension\n    twoMeters <- 2m\n\n    //RegEx\n    matchSteves <- /[S|s]te(?:ven?|phen)/\n\n//EOF"
    },

    "ifStatement": {
      "pattern": "if-statement-comprehensive",
      "description": "If statements with guards, declarations, and range checks",
      "keywords": ["if", "else", "when", "guard", "<-", ":=", "?="],
      "code": "#!ek9\ndefines module example.flowcontrol\n\n  defines function\n\n    getTemperature()\n      -> country as String\n      <- temperature <- Integer()\n      if country == \"GB\"\n        temperature :=? 20\n      else if country == \"US\"\n        temperature :=? 75\n\n  defines program\n\n    Demo()\n      stdout <- Stdout()\n\n      //Simple if\n      score <- 9\n      if score < 10\n        stdout.println(\"Less than 10\")\n\n      //If-else chain\n      result <- String()\n      if score > 9\n        result: \"Too High\"\n      else if score < 9\n        result: \"Too Low\"\n      else\n        result: \"Just Right\"\n      stdout.println(result)\n\n      //'when' is synonym for 'if'\n      when score < 10\n        stdout.println(\"Still less than 10\")\n\n      //Guard with declaration - variable scoped to if block\n      //Block only executes if getTemperature returns SET value\n      when reading <- getTemperature(\"GB\") with reading > 10\n        stdout.println(`UK temp: ${reading}`)\n\n      //Guard with guarded assignment\n      existingTemp <- Integer()\n      if existingTemp ?= getTemperature(\"US\") with existingTemp > 50\n        stdout.println(`US is hot: ${existingTemp}`)\n\n      //Range check\n      x <- 15\n      if x in 10 ... 20\n        stdout.println(\"x is between 10 and 20\")\n\n      if x not in 1 ... 5\n        stdout.println(\"x is not between 1 and 5\")\n\n//EOF"
    },

    "switchStatement": {
      "pattern": "switch-statement-comprehensive",
      "description": "Switch with case, expressions, comparison operators, and guards - NO fallthrough",
      "keywords": ["switch", "given", "case", "when", "default"],
      "code": "#!ek9\ndefines module example.switch\n\n  defines type\n\n    Status\n      Active, Pending, Closed\n\n  defines function\n\n    getCurrentTemp()\n      <- rtn <- 20\n\n  defines program\n\n    Demo()\n      stdout <- Stdout()\n\n      //'switch' and 'given' are synonyms\n      //'case' and 'when' are synonyms\n      //NO fallthrough - each case is independent (by design)\n\n      //Basic switch\n      status <- Status.Active\n      switch status\n        case Status.Active\n          stdout.println(\"Processing...\")\n        case Status.Pending\n          stdout.println(\"Waiting...\")\n        default\n          stdout.println(\"Done\")\n\n      //Switch as expression - returns a value\n      score <- 25\n      result <- given score\n        <- rtn as String?\n        when < 10\n          rtn: \"Low\"\n        when 20, 21, 22, 23, 24\n          rtn: \"Perfect\"\n        when > 30\n          rtn: \"High\"\n        default\n          rtn: \"OK\"\n      stdout.println(`Result: ${result}`)\n\n      //Multiple values in one case (replaces fallthrough)\n      day <- 3\n      dayType <- switch day\n        <- rtn as String?\n        case 1, 7\n          rtn: \"Weekend\"\n        case 2, 3, 4, 5, 6\n          rtn: \"Weekday\"\n        default\n          rtn: \"Unknown\"\n\n      //Switch with comparison operators\n      multiplier <- 5\n      category <- switch score\n        <- rtn as String?\n        case < 12\n          rtn: \"Moderate\"\n        case > 10*multiplier\n          rtn: \"Very High\"\n        case getCurrentTemp(), 21, 22\n          rtn: \"Perfect\"\n        default\n          rtn: \"Suitable\"\n\n      //Switch with guard declaration\n      text <- switch reading <- getCurrentTemp() with reading\n        <- rtn as String?\n        case < 15\n          rtn: `Cold: ${reading}`\n        case > 25\n          rtn: `Hot: ${reading}`\n        default\n          rtn: `Nice: ${reading}`\n\n      stdout.println(text)\n\n//EOF"
    },

    "forLoop": {
      "pattern": "for-loop-comprehensive",
      "description": "For loops with ranges, collections, iterators - NO break/continue",
      "keywords": ["for", "in", "by", "range", "..."],
      "code": "#!ek9\ndefines module example.forloop\n\n  defines program\n\n    Demo()\n      stdout <- Stdout()\n\n      //Range iteration (inclusive)\n      stdout.println(\"1 to 5:\")\n      for i in 1 ... 5\n        stdout.println($i)\n\n      //Range with step\n      stdout.println(\"1 to 10 by 2:\")\n      for i in 1 ... 10 by 2\n        stdout.println($i)\n\n      //Descending range\n      stdout.println(\"10 down to 1:\")\n      for i in 10 ... 1 by -1\n        stdout.println($i)\n\n      //Collection iteration\n      items <- [\"Alpha\", \"Beta\", \"Charlie\"]\n      for item in items\n        stdout.println(item)\n\n      //String iteration (characters)\n      for char in \"Hello\"\n        stdout.println(char)\n\n      //Iterator directly\n      iter <- items.iterator()\n      for item in iter\n        stdout.println(`Via iterator: ${item}`)\n\n      //Float range\n      for f in 1.0 ... 5.0 by 0.5\n        stdout.println($f)\n\n      //Time range\n      start <- 09:00\n      finish <- 17:00\n      for t in start ... finish by PT1H\n        stdout.println($t)\n\n      //NO break/continue in EK9!\n      //Use streams instead:\n      //cat items | filter by predicate | head\n\n//EOF"
    },

    "whileLoop": {
      "pattern": "while-loop-comprehensive",
      "description": "While and do-while loops with guards and as expressions",
      "keywords": ["while", "do", "with", "then"],
      "code": "#!ek9\ndefines module example.whileloop\n\n  defines program\n\n    Demo()\n      stdout <- Stdout()\n\n      //Basic while\n      items <- ['A', 'B', 'C']\n      iter <- items.iterator()\n      while iter.hasNext()\n        item <- iter.next()\n        stdout.println(item)\n\n      //While with guard - reset iterator only if unset\n      while iter ?= items.iterator() then iter.hasNext()\n        item <- iter.next()\n        stdout.println(`Again: ${item}`)\n\n      //While with declaration - variable scoped to loop\n      while newIter <- items.iterator() then newIter.hasNext()\n        item <- newIter.next()\n        stdout.println(`New: ${item}`)\n\n      //Do-while - body executes at least once\n      resetIter <- items.iterator()\n      if resetIter.hasNext()\n        do\n          item <- resetIter.next()\n          stdout.println(`Do: ${item}`)\n        while resetIter.hasNext()\n\n      //While as expression - returns value\n      result <- while complete <- false with not complete\n        <- rtn <- 0\n        rtn++\n        complete: rtn == 10\n      stdout.println(`While result: ${result}`)\n\n      //Do-while as expression\n      result2 <- do complete <- false\n        <- rtn <- 0\n        rtn++\n        complete: rtn == 5\n      while not complete\n      stdout.println(`Do result: ${result2}`)\n\n//EOF"
    },

    "tryCatch": {
      "pattern": "exception-handling-comprehensive",
      "description": "Try/catch/finally with guards, custom exceptions, and dispatcher pattern",
      "keywords": ["try", "catch", "handle", "finally", "throw", "Exception"],
      "code": "#!ek9\ndefines module example.exceptions\n\n  defines class\n\n    //Custom exception with additional field\n    ValidationException extends Exception\n      fieldName <- String()\n\n      ValidationException()\n        ->\n          message as String\n          fieldName as String\n        super(message, 1)\n        this.fieldName :=? fieldName\n\n      fieldName() as pure\n        <- rtn as String: fieldName\n\n      override operator $ as pure\n        <- rtn as String: `${reason()} [field: ${fieldName}]`\n\n    Processor\n\n      process()\n        -> number as Integer\n        <- rtn as String?\n\n        if number < 0\n          throw ValidationException(\"Negative not allowed\", \"number\")\n        else if number > 100\n          throw Exception(\"Too large\", 2)\n        else\n          rtn: `Processed: ${number}`\n\n      //Dispatcher for type-specific exception handling\n      handleError() as dispatcher\n        -> ex as Exception\n        <- rtn as String: $ex\n\n      handleError()\n        -> ex as ValidationException\n        <- rtn as String: `Validation failed: ${ex.fieldName()}`\n\n  defines program\n\n    Demo()\n      stdout <- Stdout()\n      stderr <- Stderr()\n      processor <- Processor()\n\n      for number in [-1, 50, 150]\n        try\n          result <- processor.process(number)\n          stdout.println(result)\n        catch\n          -> ex as Exception\n          //Dispatcher routes to specific handler\n          stderr.println(processor.handleError(ex))\n        finally\n          stdout.println(`Finished processing ${number}`)\n\n      //Try with resource auto-close\n      try\n        -> input <- TextFile(\"test.txt\").input()\n        cat input > stdout\n      handle\n        -> ex as Exception\n        stderr.println($ex)\n      finally\n        stdout.println(\"File auto-closed\")\n\n//EOF"
    },

    "streams": {
      "pattern": "stream-pipelines",
      "description": "Stream pipelines replace loops with break/continue - cat, filter, map, head, collect",
      "keywords": ["cat", "|", "filter", "map", "head", "tail", "collect", ">"],
      "code": "#!ek9\ndefines module example.streams\n\n  defines function\n\n    isEven() as pure\n      -> n as Integer\n      <- rtn as Boolean: n mod 2 == 0\n\n    double() as pure\n      -> n as Integer\n      <- rtn as Integer: n * 2\n\n    formatItem() as pure\n      -> n as Integer\n      <- rtn as String: `Item: ${n}`\n\n    joinWithComma() as pure\n      ->\n        a as String\n        b as String\n      <- rtn as String: a? and b? <- a + \", \" + b : String()\n\n  defines program\n\n    Demo()\n      stdout <- Stdout()\n      numbers <- [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\n\n      //Output directly to stdout\n      stdout.println(\"All numbers:\")\n      cat numbers > stdout\n\n      //Filter - replaces continue pattern\n      stdout.println(\"Even numbers:\")\n      cat numbers | filter by isEven > stdout\n\n      //Map - transform each item\n      stdout.println(\"Doubled:\")\n      cat numbers | map by double > stdout\n\n      //Head - replaces break pattern (take first N)\n      stdout.println(\"First 3:\")\n      cat numbers | head 3 > stdout\n\n      //Tail - last N items\n      stdout.println(\"Last 3:\")\n      cat numbers | tail 3 > stdout\n\n      //Skip - skip first N\n      stdout.println(\"Skip first 5:\")\n      cat numbers | skip 5 > stdout\n\n      //Chain multiple operations\n      stdout.println(\"Even, doubled, first 3:\")\n      cat numbers | filter by isEven | map by double | head 3 > stdout\n\n      //Collect into List\n      evens <- cat numbers | filter by isEven | collect as List of Integer\n      stdout.println(`Collected evens: ${evens}`)\n\n      //Collect into String with join\n      formatted <- cat numbers\n        | map by formatItem\n        | join with joinWithComma\n        | collect as String\n      stdout.println(`Joined: ${formatted}`)\n\n      //Range as stream source\n      stdout.println(\"Range stream:\")\n      for i in 1 ... 5 | map by double > stdout\n\n//EOF"
    },

    "generics": {
      "pattern": "generic-types",
      "description": "Generic/parameterized types - List of T, Optional of T, custom generics",
      "keywords": ["of", "List", "Dict", "Optional", "generic", "constrain"],
      "code": "#!ek9\ndefines module example.generics\n\n  defines function\n\n    //Generic function\n    identity() of type T\n      -> item as T\n      <- rtn as T: item\n\n    //Generic with constraint\n    findMax() of type T constrain by Comparable\n      ->\n        a as T\n        b as T\n      <- rtn as T: a > b <- a else b\n\n  defines class\n\n    //Generic class\n    Container of type T\n      item as T?\n\n      Container()\n        -> item as T\n        this.item :=? item\n\n      get() as pure\n        <- rtn as T: item\n\n      set()\n        -> newItem as T\n        item :=: newItem\n\n      operator ? as pure\n        <- rtn as Boolean: item?\n\n  defines program\n\n    Demo()\n      stdout <- Stdout()\n\n      //Built-in generic types\n      strings <- List() of String\n      strings += \"Hello\"\n      strings += \"World\"\n      stdout.println(`List: ${strings}`)\n\n      //Dict (key-value)\n      ages <- Dict() of String, Integer\n      ages += DictEntry(\"Steve\", 30)\n      ages += DictEntry(\"John\", 25)\n      stdout.println(`Dict: ${ages}`)\n\n      //Optional\n      maybeValue <- Optional(42) of Integer\n      if maybeValue?\n        stdout.println(`Optional has: ${maybeValue.get()}`)\n\n      empty <- Optional() of String\n      stdout.println(`Empty optional is set: ${empty?}`)\n\n      //Custom generic\n      container <- Container(\"test\") of String\n      stdout.println(`Container: ${container.get()}`)\n\n      //Generic functions\n      result <- identity(\"Hello\") of String\n      stdout.println(`Identity: ${result}`)\n\n      max <- findMax(10, 20) of Integer\n      stdout.println(`Max: ${max}`)\n\n//EOF"
    },

    "dynamicFunctions": {
      "pattern": "dynamic-functions-and-closures",
      "description": "Dynamic functions with capture - EK9's approach to closures/lambdas",
      "keywords": ["dynamic", "function", "capture", "is", "as function"],
      "code": "#!ek9\ndefines module example.dynamic\n\n  defines function\n\n    //Abstract function to implement\n    predicate() as pure abstract\n      -> number as Integer\n      <- rtn as Boolean?\n\n    transformer() as pure abstract\n      -> number as Integer\n      <- rtn as Integer?\n\n  defines program\n\n    Demo()\n      stdout <- Stdout()\n\n      threshold <- 10\n      multiplier <- 3\n\n      //Dynamic function capturing 'threshold'\n      greaterThan <- (threshold) is predicate as function\n        rtn: number > threshold\n\n      //Dynamic function capturing 'multiplier'\n      multiply <- (multiplier) is transformer\n        rtn: number * multiplier\n\n      //Test the dynamic functions\n      for n in [5, 10, 15]\n        if greaterThan(n)\n          stdout.println(`${n} > ${threshold}: ${multiply(n)}`)\n\n      //Inline lambda-like syntax (single expression)\n      lessThan <- (threshold) is predicate as pure (rtn: number < threshold)\n\n      //Multiple captures with named parameters\n      inRange <- (lo: 5, hi: 15) is predicate as pure (rtn: number > lo and number < hi)\n\n      //Functions as values in list\n      predicates <- [\n        (threshold) is predicate as pure (rtn: number == threshold),\n        greaterThan,\n        lessThan\n        ]\n\n      for pred in predicates\n        stdout.println(`10 matches: ${pred(10)}`)\n\n//EOF"
    },

    "ternaryOperators": {
      "pattern": "ternary-and-coalescing",
      "description": "Ternary conditional, null coalescing, elvis, min/max selection operators",
      "keywords": ["<-", ":", "??", "?:", "<?", ">?"],
      "code": "#!ek9\ndefines module example.ternary\n\n  defines program\n\n    Demo()\n      stdout <- Stdout()\n\n      //Ternary conditional: condition <- trueValue : falseValue\n      x <- 15\n      result <- x > 10 <- \"big\" : \"small\"\n      stdout.println(`x is ${result}`)\n\n      //isSet check in condition\n      name <- String()\n      display <- name? <- name : \"Anonymous\"\n      stdout.println(`Display: ${display}`)\n\n      //Null coalescing ?? - return left if SET, else right\n      value1 <- String()\n      value2 <- \"Default\"\n      coalesced <- value1 ?? value2\n      stdout.println(`Coalesced: ${coalesced}`)\n\n      //Elvis ?: - same as ?? (isSet check)\n      elvis <- value1 ?: \"Elvis default\"\n      stdout.println(`Elvis: ${elvis}`)\n\n      //Min selection <? - return smaller value\n      a <- 5\n      b <- 10\n      minVal <- a <? b\n      stdout.println(`Min: ${minVal}`)\n\n      //Max selection >? - return larger value\n      maxVal <- a >? b\n      stdout.println(`Max: ${maxVal}`)\n\n      //Works with unset values - returns the SET one\n      unsetNum <- Integer()\n      setNum <- 42\n      selected <- unsetNum <? setNum\n      stdout.println(`Selected: ${selected}`)\n\n      //Chained ternary for complex selection\n      status <- 2\n      message <- status == 0 <- \"OK\" : status == 1 <- \"Warning\" : \"Error\"\n      stdout.println(`Status: ${message}`)\n\n//EOF"
    },

    "records": {
      "pattern": "record-with-operators",
      "description": "Records with operators: copy :=:, merge :~:, JSON $$, String $, comparison <=>. Records can have ALL operators (unlike structs in other languages). Use 'default operator' for auto-generation.",
      "keywords": ["record", ":=:", ":~:", "<~>", "<=>", "extends", "$$", "$", "default"],
      "code": "#!ek9\ndefines module example.records\n\n  defines type\n\n    //Constrained type\n    PositiveId as Integer constrain as\n      > 0\n\n  defines record\n\n    //Base record\n    IdRecord as abstract\n      id <- PositiveId()\n\n      IdRecord()\n        -> id as PositiveId\n        require id?\n        this.id :=? id\n\n      operator $ as pure\n        <- rtn as String: $id\n\n      operator ? as pure\n        <- rtn as Boolean: id?\n\n    //Extended record with manual operators\n    Person extends IdRecord\n      firstName as String: String()\n      lastName as String: String()\n\n      Person()\n        ->\n          id as PositiveId\n          firstName as String\n          lastName as String\n        super(id)\n        this.firstName :=? firstName\n        this.lastName :=? lastName\n\n      //Copy operator - deep copy all fields\n      operator :=:\n        -> other as Person\n        id :=: other.id\n        firstName :=: other.firstName\n        lastName :=: other.lastName\n\n      //Merge operator - only copy unset fields\n      operator :~:\n        -> other as Person\n        if not id?\n          id :=: other.id\n        if not firstName?\n          firstName :=: other.firstName\n        if not lastName?\n          lastName :=: other.lastName\n\n      //Fuzzy match - similarity score\n      operator <~> as pure\n        -> other as Person\n        <- rtn as Integer: (firstName <~> other.firstName) + (lastName <~> other.lastName)\n\n      //Comparison\n      operator <=> as pure\n        -> other as Person\n        <- rtn as Integer: (lastName <=> other.lastName) + (firstName <=> other.firstName)\n\n      override operator $ as pure\n        <- rtn as String: `${super.$()} ${firstName} ${lastName}`\n\n      override operator ? as pure\n        <- rtn as Boolean: super.?() and firstName? and lastName?\n\n    //Record using 'default operator' for auto-generated implementations\n    //Records can have ALL operators - don't write manual conversion functions!\n    Customer\n      name as String: String()\n      email as String: String()\n      age as Integer: Integer()\n\n      Customer()\n        ->\n          name as String\n          email as String\n          age as Integer\n        this.name :=? name\n        this.email :=? email\n        this.age :=? age\n\n      //Auto-generated JSON: {\"name\":\"...\",\"email\":\"...\",\"age\":...}\n      default operator $$\n\n      //Auto-generated String display\n      default operator $\n\n      //Auto-generated deep copy, equality, isSet, comparison, hashcode\n      default operator :=:\n      default operator ==\n      default operator ?\n      default operator <=>\n      default operator #?\n\n  defines program\n\n    Demo()\n      stdout <- Stdout()\n\n      p1 <- Person(PositiveId(1), \"Steve\", \"Limb\")\n      p2 <- Person(PositiveId(2), \"Stephen\", \"Limb\")\n\n      //Fuzzy match\n      similarity <- p1 <~> p2\n      stdout.println(`Similarity: ${similarity}`)\n\n      //Copy\n      p3 <- Person()\n      p3 :=: p1\n      stdout.println(`Copied: ${p3}`)\n\n      //Merge partial records\n      partial1 <- Person(PositiveId(1), \"Steve\", String())\n      partial2 <- Person(PositiveId(1), String(), \"Limb\")\n      partial1 :~: partial2\n      stdout.println(`Merged: ${partial1}`)\n\n      //Customer with default operators - NO manual JSON functions needed!\n      c1 <- Customer(\"Steve\", \"steve@example.com\", 30)\n\n      //$$record produces JSON automatically\n      json <- $$c1\n      stdout.println(`JSON: ${json}`)\n\n      //$record produces String automatically\n      stdout.println(`String: ${c1}`)\n\n      //Works on Lists too - $$ on List of Customer produces JSON array\n      customers <- [c1, Customer(\"Jane\", \"jane@example.com\", 25)]\n      stdout.println(`All: ${$$customers}`)\n\n//EOF"
    },

    "sanitization": {
      "pattern": "sanitized-input",
      "description": "Input sanitization for security - 'sanitized' modifier on String parameters",
      "keywords": ["sanitized", "String", "security", "InputSanitizer"],
      "code": "#!ek9\ndefines module example.security\n\n  defines function\n\n    //Sanitized parameter - automatically validated\n    //Block only executes if input passes security checks\n    processInput()\n      -> sanitized input as String\n      <- rtn as String: String()\n\n      if input?\n        //Safe to use - guaranteed clean\n        rtn: `Processed: ${input}`\n\n    //Manual sanitization using InputSanitizer\n    manualCheck()\n      -> userInput as String\n      <- rtn as String: String()\n\n      sanitizer <- InputSanitizer()\n      if clean <- sanitizer.sanitize(userInput)\n        rtn: `Manual clean: ${clean}`\n\n  defines program\n\n    Demo()\n      stdout <- Stdout()\n      stderr <- Stderr()\n\n      //Safe input\n      safeInput <- \"Hello World\"\n      result <- processInput(safeInput)\n      stdout.println(result)\n\n      //Potentially malicious input (SQL injection attempt)\n      badInput <- \"'; DROP TABLE users; --\"\n      result2 <- processInput(badInput)\n      if result2?\n        stdout.println(result2)\n      else\n        stderr.println(\"Input rejected as unsafe\")\n\n      //Manual sanitization with threat detection\n      sanitizer <- InputSanitizer()\n      threat <- sanitizer.detectThreat(badInput)\n      if threat?\n        stderr.println(`Threat detected: ${threat}`)\n\n//EOF"
    },

    "dispatcherPattern": {
      "pattern": "dispatcher-double-dispatch",
      "description": "Dispatcher pattern - EK9's replacement for instanceof/casting",
      "keywords": ["dispatcher", "method", "polymorphism", "override"],
      "code": "#!ek9\ndefines module example.dispatcher\n\n  defines class\n\n    //Base shape class\n    Shape as abstract\n      name() as pure abstract\n        <- rtn as String?\n\n    Circle extends Shape\n      radius <- Float()\n\n      Circle()\n        -> radius as Float\n        this.radius :=? radius\n\n      override name() as pure\n        <- rtn as String: \"Circle\"\n\n      radius() as pure\n        <- rtn as Float: radius\n\n    Square extends Shape\n      side <- Float()\n\n      Square()\n        -> side as Float\n        this.side :=? side\n\n      override name() as pure\n        <- rtn as String: \"Square\"\n\n      side() as pure\n        <- rtn as Float: side\n\n    //Renderer uses dispatcher for type-specific behavior\n    Renderer\n\n      //Dispatcher method - entry point\n      render() as dispatcher\n        -> shape as Shape\n        <- rtn as String: `Unknown shape: ${shape.name()}`\n\n      //Specific handler for Circle\n      render()\n        -> shape as Circle\n        <- rtn as String: `Circle with radius ${shape.radius()}`\n\n      //Specific handler for Square\n      render()\n        -> shape as Square\n        <- rtn as String: `Square with side ${shape.side()}`\n\n  defines program\n\n    Demo()\n      stdout <- Stdout()\n      renderer <- Renderer()\n\n      shapes <- [Circle(5.0), Square(3.0)]\n\n      //Compiler routes to correct overload automatically\n      //NO instanceof, NO casting needed!\n      for shape in shapes\n        stdout.println(renderer.render(shape))\n\n//EOF"
    },

    "restService": {
      "pattern": "rest-web-service",
      "description": "REST service with HTTP method mapping - GET, POST, DELETE, PATCH, PUT via operators",
      "keywords": ["service", "REST", "GET", "POST", "DELETE", "PATCH", "PUT", "PATH", "REQUEST", "CONTENT", "HTTPResponse"],
      "code": "#!ek9\ndefines module example.restservice\n\n  defines function\n\n    //Helper to create a non-cacheable HTTP response base\n    plainResponse()\n      <- rtn as HTTPResponse: () with trait of HTTPResponse\n        override cacheControl() as pure\n          <- rtn as String: \"no-store,max-age=0\"\n        override contentType() as pure\n          <- rtn as String: \"application/json\"\n        override contentLanguage() as pure\n          <- rtn as String: \"en\"\n        default operator ?\n\n  defines service\n\n    //Service mapped to /items URI path\n    Items :/items\n\n      //GET with path parameter - maps to /items/{item-id}\n      byId() as GET for :/{item-id}\n        -> id as String :=: PATH \"item-id\"\n        <- response as HTTPResponse: (id: id, base: plainResponse()) with trait of HTTPResponse by base\n          override status() as pure\n            <- rtn as Integer: id? <- 200 : 404\n          override content()\n            <- rtn as String: String()\n          default operator ?\n\n      //POST - operator += maps to HTTP POST\n      operator += :/\n        -> request as HTTPRequest :=: REQUEST\n        <- response as HTTPResponse: (request: request, base: plainResponse()) with trait of HTTPResponse by base\n          status as Integer: 201\n          override content()\n            <- rtn as String: request.content()\n          override status() as pure\n            <- rtn as Integer: status\n          default operator ?\n\n      //DELETE - operator -= maps to HTTP DELETE\n      operator -= :/{id}\n        -> id as String\n        <- response as HTTPResponse: (base: plainResponse()) with trait of HTTPResponse by base\n          override status() as pure\n            <- rtn as Integer: 204\n          default operator ?\n\n      //PATCH - operator :~: maps to HTTP PATCH (merge)\n      operator :~: :/{id}\n        ->\n          id as String\n          content as String :=: CONTENT\n        <- response as HTTPResponse: (base: plainResponse()) with trait of HTTPResponse by base\n          override status() as pure\n            <- rtn as Integer: 204\n          default operator ?\n\n      //PUT - operator :^: maps to HTTP PUT (replace)\n      operator :^: :/{id}\n        ->\n          id as String\n          content as String :=: CONTENT\n        <- response as HTTPResponse: (base: plainResponse()) with trait of HTTPResponse by base\n          override status() as pure\n            <- rtn as Integer: 200\n          default operator ?\n\n      //GET all items at root URI\n      listAll() :/\n        <- response as HTTPResponse: (base: plainResponse()) with trait of HTTPResponse by base\n          override content()\n            <- rtn as String: \"[]\"\n          default operator ?\n\n//EOF"
    },

    "textProperties": {
      "pattern": "text-i18n-localization",
      "description": "Text constructs for internationalization - locale-specific templates with string interpolation",
      "keywords": ["text", "locale", "i18n", "interpolation", "backtick", "template"],
      "code": "#!ek9\ndefines module example.text\n\n  defines record\n\n    Person\n      firstName as String: String()\n      lastName as String: String()\n\n      Person()\n        ->\n          firstName as String\n          lastName as String\n        this.firstName :=? firstName\n        this.lastName :=? lastName\n\n      operator $ as pure\n        <- rtn as String: `${firstName} ${lastName}`\n\n  defines text for \"en\"\n\n    WelcomePage\n\n      //Backticks for interpolated template strings\n      greeting()\n        -> person as Person\n        `Welcome ${person.firstName} ${person.lastName}`\n\n      //Quotes for literal (non-interpolated) text\n      mainMessage()\n        \"Welcome to our application.\"\n\n      //Escaped $ with \\$ for literal dollar sign\n      priceInfo()\n        -> amount as String\n        `Total: \\$${amount}`\n\n    Validator\n\n      tooShort()\n        -> input as String\n        `The value '${input}' is too short`\n\n  defines text for \"de\"\n\n    WelcomePage\n\n      greeting()\n        -> person as Person\n        `Willkommen ${person.firstName} ${person.lastName}`\n\n      mainMessage()\n        \"Willkommen in unserer Anwendung.\"\n\n      priceInfo()\n        -> amount as String\n        `Gesamt: \\$${amount}`\n\n    Validator\n\n      tooShort()\n        -> input as String\n        `Der Wert '${input}' ist zu kurz`\n\n  defines program\n\n    Demo()\n      stdout <- Stdout()\n      person <- Person(\"Steve\", \"Limb\")\n\n      //Runtime locale selection via constructor argument\n      english <- WelcomePage(\"en\")\n      stdout.println(english.greeting(person))\n      stdout.println(english.mainMessage())\n      stdout.println(english.priceInfo(\"42.00\"))\n\n      //Switch to German locale\n      deutsch <- WelcomePage(\"de\")\n      stdout.println(deutsch.greeting(person))\n\n      //Validation messages follow same locale pattern\n      validator <- Validator(\"en\")\n      stdout.println(validator.tooShort(\"Hi\"))\n\n//EOF"
    },

    "componentApplication": {
      "pattern": "component-application-di",
      "description": "Components, applications, and dependency injection - register bindings and inject with '!'",
      "keywords": ["component", "application", "register", "injection", "DI"],
      "code": "#!ek9\ndefines module example.components\n\n  defines trait\n\n    Logger\n      log() abstract\n        -> message as String\n\n    DataStore\n      save() abstract\n        -> content as String\n        <- rtn as Boolean?\n\n      load() abstract\n        -> id as String\n        <- rtn as String?\n\n  defines component\n\n    //Abstract component - defines injection interface\n    AppLogger as abstract\n      logger() as pure abstract\n        <- rtn as Logger?\n\n    //Concrete component - provides implementation\n    ConsoleLogger is AppLogger\n      override logger() as pure\n        <- rtn as Logger: () with trait of Logger\n          override log()\n            -> message as String\n            Stdout().println(message)\n          default operator ?\n\n    //Abstract data store component\n    AppDataStore as abstract\n      store() as pure abstract\n        <- rtn as DataStore?\n\n    //In-memory implementation\n    MemoryDataStore is AppDataStore\n      override store() as pure\n        <- rtn as DataStore: () with trait of DataStore\n          override save()\n            -> content as String\n            <- rtn as Boolean: content?\n          override load()\n            -> id as String\n            <- rtn as String: `Data for ${id}`\n          default operator ?\n\n  defines application\n\n    //Application wires components together\n    //register creates singleton bindings: implementation as abstract type\n    MyApp\n      register ConsoleLogger() as AppLogger\n      register MemoryDataStore() as AppDataStore\n\n  defines program\n\n    //Program with DI - 'with application of' enables injection\n    Demo() with application of MyApp\n      //The '!' suffix marks fields for dependency injection\n      appLogger as AppLogger!\n      dataStore as AppDataStore!\n\n      logger <- appLogger.logger()\n      store <- dataStore.store()\n\n      logger.log(\"Starting application\")\n\n      if store.save(\"test payload\")\n        logger.log(\"Data saved successfully\")\n\n      result <- store.load(\"item-1\")\n      if result?\n        logger.log(`Loaded: ${result}`)\n\n//EOF"
    },

    "transactionManagement": {
      "pattern": "transaction-management",
      "description": "Transaction trait for ACID-compliant operations with try-with-resources auto-cleanup",
      "keywords": ["transaction", "commit", "rollback", "Closeable", "ACID", "try-with-resources", "Transaction"],
      "code": "#!ek9\ndefines module example.transaction\n\n  defines class\n\n    //Implement Transaction trait for ACID operations\n    //Transaction extends Closeable - auto-cleanup in try blocks\n    DatabaseTransaction with trait of Transaction\n      committed <- Boolean()\n\n      override commit()\n        committed: true\n\n      override rollback()\n        committed: false\n\n      override isCommitted() as pure\n        <- rtn as Boolean: Boolean(committed)\n\n      //close is called automatically at end of try block\n      //Safety net: rollback if not committed\n      override operator close\n        if not isCommitted()\n          rollback()\n\n  defines program\n\n    Demo()\n      stdout <- Stdout()\n\n      //try-with-resources: close called automatically\n      try\n        -> txn <- DatabaseTransaction()\n        stdout.println(\"Processing...\")\n        txn.commit()\n        stdout.println(`Committed: ${txn.isCommitted()}`)\n      catch\n        -> ex as Exception\n        stdout.println(`Failed: ${$ex}`)\n\n//EOF"
    }
  },

  "keywordIndex": {
    "description": "Quick lookup of keywords to relevant inline examples",
    "program": ["helloWorld", "simpleFunction"],
    "module": ["helloWorld", "constants"],
    "function": ["simpleFunction", "abstractFunction"],
    "class": ["simpleClass", "classExtension", "dynamicFunctions"],
    "record": ["records"],
    "trait": ["traitComposition"],
    "type": ["enumeration", "constants"],
    "enum": ["enumeration"],
    "extends": ["classExtension", "records"],
    "override": ["classExtension", "traitComposition"],
    "abstract": ["abstractFunction", "classExtension"],
    "pure": ["simpleFunction", "abstractFunction"],
    "if": ["ifStatement"],
    "switch": ["switchStatement", "enumeration"],
    "given": ["switchStatement"],
    "for": ["forLoop", "enumeration"],
    "while": ["whileLoop"],
    "try": ["tryCatch"],
    "catch": ["tryCatch"],
    "finally": ["tryCatch"],
    "cat": ["streams"],
    "filter": ["streams"],
    "map": ["streams"],
    "head": ["streams"],
    "tail": ["streams"],
    "collect": ["streams"],
    "pipe": ["streams"],
    "stream": ["streams"],
    "of": ["generics"],
    "List": ["generics", "streams"],
    "Dict": ["generics"],
    "Optional": ["generics"],
    "generic": ["generics"],
    "dynamic": ["dynamicFunctions"],
    "capture": ["dynamicFunctions"],
    "closure": ["dynamicFunctions"],
    "ternary": ["ternaryOperators"],
    "coalesce": ["ternaryOperators"],
    "??": ["ternaryOperators"],
    "?:": ["ternaryOperators"],
    "dispatcher": ["dispatcherPattern", "tryCatch"],
    "sanitized": ["sanitization"],
    "constant": ["constants"],
    "operator": ["simpleClass", "records", "enumeration"],
    "guard": ["ifStatement", "switchStatement", "whileLoop"],
    "service": ["restService"],
    "REST": ["restService"],
    "GET": ["restService"],
    "POST": ["restService"],
    "DELETE": ["restService"],
    "PATCH": ["restService"],
    "PUT": ["restService"],
    "PATH": ["restService"],
    "REQUEST": ["restService"],
    "CONTENT": ["restService"],
    "HTTPResponse": ["restService"],
    "HTTPRequest": ["restService"],
    "text": ["textProperties"],
    "i18n": ["textProperties"],
    "locale": ["textProperties"],
    "interpolation": ["textProperties"],
    "template": ["textProperties"],
    "component": ["componentApplication"],
    "application": ["componentApplication"],
    "register": ["componentApplication"],
    "injection": ["componentApplication"],
    "DI": ["componentApplication"],
    "transaction": ["transactionManagement", "componentApplication"],
    "Transaction": ["transactionManagement"],
    "commit": ["transactionManagement"],
    "rollback": ["transactionManagement"],
    "ACID": ["transactionManagement"],
    "$": ["simpleClass", "records"],
    "$$": ["records"],
    "default": ["simpleClass", "records", "enumeration"],
    "JSON": ["records", "restService"],
    "default operator": ["simpleClass", "records"]
  },

  "qaSystem": {
    "description": "Built-in Q&A knowledge base for developers and AI assistants",
    "listQuestions": "ek9 -q",
    "askQuestion": "ek9 -q <words> (EK9-focused: answer + code example)",
    "askQuestionById": "ek9 -q <number> (direct Q&A fetch by ID)",
    "askMigration": "ek9 -qm <words> (migration-focused: answer + language comparisons)",
    "trainingDump": "ek9 -Q (instruction JSONL to stdout)",
    "trainingDumpChat": "ek9 -Qc (mlx_lm chat JSONL to stdout, resolved cross-refs)",
    "trainingDumpChatThinking": "ek9 -Qct (mlx_lm chat JSONL with Qwen3 thinking traces)",
    "trainingDumpSplit": "ek9 -Qt (write ek9_training_data/train.jsonl + valid.jsonl, 90/10 stratified)",
    "trainingDumpSplitThinking": "ek9 -Qtt (training split with Qwen3 thinking traces)",
    "totalQuestionsImplemented": 565,
    "categoriesImplemented": 49,
    "totalQuestionsPlanned": 2034,
    "categoriesPlanned": 197,
    "format": "JSONL instruction/response (-Q) or mlx_lm chat with system prompt (-Qc/-Qt/-Qct/-Qtt)",
    "languagesCovered": ["Python", "Java", "Rust", "Go", "C++", "Kotlin", "TypeScript", "C#"]
  }
}
