{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "stack": "go",
  "description": "Go code-graph rules. Adds what the graph needs on top of test-gap-rules/go.json, which already owns sourceExtensions, excludePathGlobs and the test-path predicates. Definition patterns here are deliberately broader than the test-gap publicApiPatterns: the graph wants unexported declarations too, because Phase 1 narrows scope on the whole package, not just its exported surface.",
  "comments": {
    "line": ["//"],
    "block": [["/*", "*/"]],
    "string": ["`", "\"", "'"]
  },
  "importSpecifiersAreStrings": true,
  "definitionPatterns": [
    {
      "id": "struct",
      "kind": "struct",
      "regex": "\\btype\\s+([A-Za-z_][A-Za-z0-9_]*)\\s+struct\\b"
    },
    {
      "id": "interface",
      "kind": "interface",
      "regex": "\\btype\\s+([A-Za-z_][A-Za-z0-9_]*)\\s+interface\\b"
    },
    {
      "id": "type",
      "kind": "type",
      "regex": "\\btype\\s+([A-Za-z_][A-Za-z0-9_]*)\\s+(?!struct\\b|interface\\b)[A-Za-z_*\\[]"
    },
    {
      "id": "func",
      "kind": "func",
      "regex": "^func\\s+(?:\\([^)]*\\)\\s+)?([A-Za-z_][A-Za-z0-9_]*)\\s*[(\\[]"
    }
  ],
  "importPatterns": [
    {
      "id": "specifier",
      "regex": "^[ \\t]*(?:import[ \\t]+)?(?:[A-Za-z_.][A-Za-z0-9_]*[ \\t]+)?\"(?:[^\"]*/)?([A-Za-z_][A-Za-z0-9_.-]*)\"[ \\t]*$"
    }
  ],
  "referenceKinds": ["struct", "interface", "type"],
  "referenceKindsNote": "func is deliberately absent, for the reason the Swift, Kotlin, Node and Python rules all record: a bare name matched across files is almost never a call to that exact declaration, and Go's short-name convention (New, Run, Get, Close, Error) makes it worse than most. Functions still reach the graph through their defines edge, so they stay findable by name.",
  "ignoredIdentifiers": [
    "package",
    "import",
    "func",
    "type",
    "struct",
    "interface",
    "map",
    "chan",
    "var",
    "const",
    "return",
    "if",
    "else",
    "for",
    "range",
    "switch",
    "case",
    "default",
    "select",
    "go",
    "defer",
    "break",
    "continue",
    "fallthrough",
    "goto",
    "nil",
    "true",
    "false",
    "iota",
    "make",
    "new",
    "len",
    "cap",
    "append",
    "copy",
    "delete",
    "panic",
    "recover",
    "print",
    "println",
    "error",
    "string",
    "bool",
    "byte",
    "rune",
    "int",
    "int8",
    "int16",
    "int32",
    "int64",
    "uint",
    "uint8",
    "uint16",
    "uint32",
    "uint64",
    "float32",
    "float64",
    "complex64",
    "complex128",
    "uintptr",
    "any",
    "comparable",
    "err",
    "ctx",
    "ok"
  ],
  "note": "A Go import path is a string literal, so `importSpecifiersAreStrings` applies exactly as it does for JavaScript: the import pass reads a text with comments stripped and strings intact, and the pattern captures the last path segment, which is the package name in the overwhelmingly common case where the two agree. The pattern is anchored to a whole line holding nothing but an optional `import`, an optional alias and the quoted path, because Go has no import keyword on the lines inside a parenthesized block. Without that anchor it matched EVERY double-quoted string in the file and turned each one into a module node. A named import (`sql \"database/sql\"`) and the handful of packages whose name differs from their directory both resolve to the directory name, which is what the engine matches against a file basename anyway. The three type patterns are ordered so `struct` and `interface` claim their shapes before the general `type` alias pattern, which excludes them by lookahead rather than by order alone - order and lookahead together, because a rule file that relies on order silently changes meaning when someone sorts it. `func` is anchored to column 0, which is where every Go function and method declaration lives; the engine's nesting rule then never has to fire for this stack.\n\nUNMEASURED: unlike ios, android, node and python, these rules were never run against a real Go codebase. There was no Go repo and no toolchain on the machine that wrote them. The smoke exercises them on a synthetic fixture, which proves they parse and produce a schema-valid graph, not that they produce a USEFUL one. Treat the first real build as the measurement, and check the hub list before trusting it."
}
