From 217974c425019874afdacb9b88a45765117f426f Mon Sep 17 00:00:00 2001 From: squid-protocol Date: Sat, 29 Aug 2026 18:27:46 -0400 Subject: [PATCH 1/4] test(recall-audit): stop counting tree-sitter's own mistakes as GitGalaxy misses Step 2.6's recall audit run against c / cpp / fortran / objective-c. Every function tree-sitter reported that GitGalaxy did not was individually read; the large majority were tree-sitter parse artifacts the accuracy audit was wrongly folding into GitGalaxy's recall denominator. Corrections, all in tree_sitter_accuracy_audit.py's ground-truth walk (real_funcs), never a gated metric: - `#if 0` / `#if false` dead-block detection (c + cpp) -- tree-sitter has no preprocessor model and parses the dead branch. `_PyObject_Managed DictValidityCheck`, `print_stack`, sqlite/lemon.c's K&R `PlinkPrint` / `SetPrint` are all inside `#if 0`. docs Claim 8's exact shape. - `_CPP_KNOWN_MACRO_HALLUCINATIONS` (mirror of `_C_...`) -- `OPCODE(X) {` (~96, godot's bytecode computed-goto table), `IFACEMETHOD_`, and the bare control-flow keywords (`if`/`for`/...) error recovery emits as a "function name" after a macro in statement position. - cpp `= default` / `= delete` special members -- not body-bearing, so GitGalaxy correctly doesn't count them (same rule as perl bodyless). - cpp function_definition with an ERROR / class_specifier child -- a corrupted `_FORCE_INLINE_`-mangled parse or a field-with-initializer (`ptr_type _value = ptr_type();`) read as a definition. Name unreliable. - cpp / fortran: a function_definition tree-sitter built INSIDE an already-identified blind spot is not ground truth -- #1849 Phase 2 already promotes GitGalaxy's correct reading there; this is the symmetric half. - fortran: a WRF-style module file's `#ifdef VERT_UNIT` unit-test driver `program X ... end program X` blocks are dead when built as a module; mark them blind spots. - objective-c `_get_node_name`: name a NeXT-era `- unsigned char foo` / `- void bar` method (no parenthesised return type) by its real selector, not by the return-type token tree-sitter picks. objc-only (the leading `-`/`+` marker gates it away from JS/TS `method_definition`). Measured (recall / precision): c 99.7% -> 100.0% / 99.5% (unchanged) cpp 89.3% -> 99.9% / 100.0% (unchanged) fortran 98.6% -> 100.0% / 100.0% (unchanged) objc 98.7% -> 100.0% / 98.1% -> 99.4% `tree_sitter_accuracy_audit --all --ci` 31/31 OK; no engine change, no golden-master re-bless. Baselines + summary table regenerated. The genuine GitGalaxy recall gaps this surfaced are filed separately (cpp macro-return-type `STDAPI Foo()`; shell keyword-as-argument; lua multi-statement `local function` line). dart's remaining 9 stay in #2072. Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_019Zm1uVBpVEZJ9SB7bWFR8S --- gitgalaxy/standards/language_standards.py | 8 +- tests/tools/tree_sitter_accuracy_audit.py | 135 +++++++++++++++++- tests/tree_sitter_accuracy_baseline_c.json | 2 +- tests/tree_sitter_accuracy_baseline_cpp.json | 2 +- ...tree_sitter_accuracy_baseline_fortran.json | 2 +- ..._sitter_accuracy_baseline_objective-c.json | 8 +- 6 files changed, 143 insertions(+), 14 deletions(-) diff --git a/gitgalaxy/standards/language_standards.py b/gitgalaxy/standards/language_standards.py index ad07ecdcd..6aa8b8bb9 100644 --- a/gitgalaxy/standards/language_standards.py +++ b/gitgalaxy/standards/language_standards.py @@ -35,12 +35,12 @@ | Language | Func Recall | Func Precision | Class Recall | Class Precision | | -------- | ----------- | -------------- | ------------ | --------------- | | Apex | 100.0% | 100.0% | 100.0% | 100.0% | -| C | 99.7% | 99.5% | 100.0% | 100.0% | -| Cpp | 89.3% | 100.0% | 100.0% | 100.0% | +| C | 100.0% | 99.5% | 100.0% | 100.0% | +| Cpp | 99.9% | 100.0% | 100.0% | 100.0% | | Csharp | 100.0% | 100.0% | 100.0% | 100.0% | | Css | 100.0% | 100.0% | N/A | N/A | | Dart | 99.5% | 99.3% | 100.0% | 100.0% | -| Fortran | 98.6% | 100.0% | 100.0% | 100.0% | +| Fortran | 100.0% | 100.0% | 100.0% | 100.0% | | Go | 100.0% | 100.0% | 100.0% | 100.0% | | Groovy | N/A | N/A | N/A | N/A | | Haskell | 100.0% | 99.3% | 100.0% | 100.0% | @@ -51,7 +51,7 @@ | Lua | 99.7% | 100.0% | N/A | 0.0% | | Makefile | 100.0% | 100.0% | N/A | N/A | | Matlab | 100.0% | 100.0% | N/A | N/A | -| Objective-C | 98.7% | 98.1% | 100.0% | 100.0% | +| Objective-C | 100.0% | 99.4% | 100.0% | 100.0% | | Perl | 100.0% | 100.0% | 100.0% | 100.0% | | Php | 100.0% | 99.9% | 100.0% | 100.0% | | Powershell | 100.0% | 100.0% | 100.0% | 100.0% | diff --git a/tests/tools/tree_sitter_accuracy_audit.py b/tests/tools/tree_sitter_accuracy_audit.py index 901bd83dd..cfe844ece 100755 --- a/tests/tools/tree_sitter_accuracy_audit.py +++ b/tests/tools/tree_sitter_accuracy_audit.py @@ -999,6 +999,25 @@ def _get_node_name(node: Any) -> Optional[str]: parts = [child.text.decode("utf8") for child in node.children if child.type == "identifier"] return ".".join(parts) if parts else None + if node.type == "method_definition" and node.children and node.children[0].type in ("-", "+"): + # #2459: an Objective-C method (the leading `-`/`+` marker is objc-only; a JavaScript / + # TypeScript `method_definition` never has one, so this branch can't touch them). NeXT-era + # objc omits the parenthesised return type -- `- unsigned char next_input_block { ... }` / + # `- void appendEndBlock { ... }`. tree-sitter-objc has no `method_type` child then and + # names the method by its first token (the return type `unsigned` / `void`); the real + # selector is the last identifier of the trailing `declaration` child, or a sibling + # `ERROR` node's text when the parse fully desyncs. GitGalaxy's func_start names these + # correctly, so without this they double-count. + if not any(c.type == "method_type" for c in node.children): + for c in node.children: + if c.type == "ERROR" and c.text.strip(): + return c.text.decode("utf8").strip() + decl = next((c for c in node.children if c.type == "declaration"), None) + if decl is not None: + toks = re.findall(r"[A-Za-z_]\w*", decl.text.decode("utf8")) + if toks: + return toks[-1] + if node.type == "operator_signature": # #Claim 5 (why_gitgalaxy_beats_ast_here.md): no child is field-tagged "name" at all -- # the operator symbol (`==`, `+`, `[]`, `[]=`, unary `-`, ...) is a plainly-typed child @@ -1894,6 +1913,48 @@ def _is_cpp_unscoped_enum(node: Any) -> bool: } ) +# #2459: the same shape as _C_KNOWN_MACRO_HALLUCINATIONS, for C++. A function-like macro whose +# invocation has the `NAME(args) {` shape tree-sitter-cpp reads as a `function_definition`: +# - OPCODE godot/gdscript_vm.cpp -- `OPCODE(OPCODE_SET_INDEXED_VALIDATED) { ... }`, +# ~96 case-label bodies in the bytecode interpreter's computed-goto table +# - IFACEMETHOD_ powertoys COM headers -- `IFACEMETHOD_(HRESULT, Foo)(...)` declaration macro +# GitGalaxy's func_start correctly excludes known function-like macro names (same fact ctags uses). +# Plus the bare control-flow keywords tree-sitter-cpp's error recovery emits as a "function name" +# when a macro with no visible expansion sits in statement position (`OBJ_DEBUG_LOCK\n if (...) {` +# -> a function_definition named `if`). A keyword is never a valid C++ identifier. +_CPP_KNOWN_MACRO_HALLUCINATIONS = frozenset( + {"OPCODE", "IFACEMETHOD_", "if", "for", "while", "switch", "do", "else", "return", "case", "goto"} +) + +_KNOWN_MACRO_HALLUCINATIONS: dict[str, frozenset[str]] = { + "c": _C_KNOWN_MACRO_HALLUCINATIONS, + "cpp": _CPP_KNOWN_MACRO_HALLUCINATIONS, +} + +_FALSY_PREPROC_CONDITIONS = frozenset({"0", "false", "FALSE", "False"}) + + +def _find_dead_preproc_ranges(root_node: Any, ts_lang: str) -> list[tuple[int, int]]: + """(start_line, end_line) spans of `#if 0` / `#if false` blocks in C/C++. tree-sitter has no + preprocessor model, so it parses the dead branch as live code -- a real function_definition + inside one is NOT ground truth GitGalaxy is wrong to skip (docs/why_gitgalaxy_beats_ast_here.md + Claim 8). #2459.""" + if ts_lang not in ("c", "cpp"): + return [] + ranges: list[tuple[int, int]] = [] + + def walk(node: Any) -> None: + if node.type == "preproc_if": + cond = node.child_by_field_name("condition") + if cond is not None and cond.text.decode("utf8").strip() in _FALSY_PREPROC_CONDITIONS: + ranges.append((node.start_point[0] + 1, node.end_point[0] + 1)) + return # nested content is all dead; don't descend + for child in node.children: + walk(child) + + walk(root_node) + return ranges + def _align_occurrences_by_line( real: list[tuple[int, int]], gg: list[tuple[int, int]] @@ -2011,6 +2072,33 @@ def _find_blind_spot_ranges(root_node: Any, ts_lang: str) -> list[tuple[int, int """ ranges = [] + if ts_lang == "fortran": + # #2459: WRF-style module files carry a `#ifdef VERT_UNIT` unit-test driver -- one or + # more top-level `program X ... end program X` blocks that are alternative compilation + # roots, DEAD when the file is built as a module (how the corpus scans it). tree-sitter + # has no preprocessor model and parses them; a `subroutine`/`call` inside one becomes a + # phantom real_funcs entry GitGalaxy is right to skip. When the file also defines a + # module, mark every `program`..`end program` statement span as a blind spot. + prog_starts: list[int] = [] + prog_ends: list[int] = [] + has_module = [False] + + def _scan(n: Any) -> None: + if n.type in ("module", "module_statement"): + has_module[0] = True + if n.type == "program_statement": + prog_starts.append(n.start_point[0] + 1) + if n.type == "end_program_statement": + prog_ends.append(n.end_point[0] + 1) + for c in n.children: + _scan(c) + + _scan(root_node) + if has_module[0] and prog_starts: + for s in prog_starts: + e = min((x for x in prog_ends if x >= s), default=s) + ranges.append((s, e)) + def walk(node: Any) -> None: if ( (ts_lang == "rust" and node.type in ("macro_definition", "macro_invocation")) @@ -2162,6 +2250,8 @@ def measure(lang: str, verbose: bool = False) -> dict: trailing_error_start = _find_trailing_error_cascade_start(tree.root_node) blind_spot_ranges = _find_blind_spot_ranges(tree.root_node, ts_lang) + dead_preproc_ranges = _find_dead_preproc_ranges(tree.root_node, ts_lang) + macro_hallucinations = _KNOWN_MACRO_HALLUCINATIONS.get(lang, frozenset()) # #1526: list, not a single int -- a name can have multiple real occurrences in # one file (property getter/setter pairs, same-named methods on different @@ -2227,8 +2317,41 @@ def walk(node, is_continuation_clause=False): # (e.g. `AbsPath`) appear twice -- once bodyless near the top, # once with a real body much later -- and only the real, # body-bearing occurrence is ever in GitGalaxy's own output. - if (lang == "perl" and node.child_by_field_name("body") is None) or ( - lang == "haskell" and is_continuation_clause + # #2459: a function_definition tree-sitter built INSIDE an + # already-identified blind spot is not trustworthy ground truth -- its + # name is parse noise (cpp `_FORCE_INLINE_` mangling) or it's a phantom + # from dead code tree-sitter has no preprocessor model for (fortran's + # `#ifdef VERT_UNIT` unit-test `program` blocks). #1849 Phase 2 already + # promotes GitGalaxy's correct reading for the region; this is the + # symmetric half. Scoped to the two langs whose blind spots can contain + # real (wrong) tree-sitter structure -- rust/zig blind spots are opaque + # macro/ERROR bodies with nothing to walk. + _in_blind_spot = lang in ("cpp", "fortran") and any( + s <= node.start_point[0] + 1 <= e for s, e in blind_spot_ranges + ) + _cpp_defaulted = lang == "cpp" and any( + c.type in ("default_method_clause", "delete_method_clause") for c in node.children + ) + # #2459: a cpp function_definition with an ERROR child (or a whole + # class_specifier swallowed as its "return type") is a corrupted parse -- + # a `_FORCE_INLINE_`-mangled member or a field-with-initializer + # (`ptr_type _value = ptr_type();`) read as a definition. Name unreliable. + _cpp_corrupt = lang == "cpp" and any( + c.type in ("ERROR", "class_specifier") for c in node.children + ) + if ( + (lang == "perl" and node.child_by_field_name("body") is None) + or (lang == "haskell" and is_continuation_clause) + # #2459: inside a tree-sitter-cpp ERROR span (a `_FORCE_INLINE_`-style + # macro before a member desyncs the parse) tree-sitter's names are + # noise -- bare `for` / `bool` / `void`, a field name read as a + # function. #2455's #1849-Phase-2 promotion already fills the region + # with GitGalaxy's correct reading; this is its symmetric half. + or _in_blind_spot + # `X() = default;` / `= delete;` -- not a body-bearing definition, so + # GitGalaxy correctly doesn't count it (same rule as perl bodyless). + or _cpp_defaulted + or _cpp_corrupt ): pass else: @@ -2297,7 +2420,13 @@ def walk(node, is_continuation_clause=False): or (lang == "javascript" and name in _JS_KNOWN_FLOW_HALLUCINATIONS) ) ) - and not (lang == "c" and name in _C_KNOWN_MACRO_HALLUCINATIONS) + and name not in macro_hallucinations + and not ( + dead_preproc_ranges + and any( + s <= node.start_point[0] + 1 <= e for s, e in dead_preproc_ranges + ) + ) ): start_line = node.start_point[0] + 1 real_funcs.setdefault(name, []).append((start_line, _get_param_count(node, lang))) diff --git a/tests/tree_sitter_accuracy_baseline_c.json b/tests/tree_sitter_accuracy_baseline_c.json index 8d2c7702d..0f1ca89b1 100644 --- a/tests/tree_sitter_accuracy_baseline_c.json +++ b/tests/tree_sitter_accuracy_baseline_c.json @@ -8,5 +8,5 @@ "found_classes": 61, "found_functions": 1713, "real_classes": 61, - "real_functions": 1719 + "real_functions": 1713 } diff --git a/tests/tree_sitter_accuracy_baseline_cpp.json b/tests/tree_sitter_accuracy_baseline_cpp.json index 9ca5b3cfe..7b1f8795e 100644 --- a/tests/tree_sitter_accuracy_baseline_cpp.json +++ b/tests/tree_sitter_accuracy_baseline_cpp.json @@ -8,5 +8,5 @@ "found_classes": 65, "found_functions": 1369, "real_classes": 65, - "real_functions": 1533 + "real_functions": 1370 } diff --git a/tests/tree_sitter_accuracy_baseline_fortran.json b/tests/tree_sitter_accuracy_baseline_fortran.json index d1584826a..570596e41 100644 --- a/tests/tree_sitter_accuracy_baseline_fortran.json +++ b/tests/tree_sitter_accuracy_baseline_fortran.json @@ -8,5 +8,5 @@ "found_classes": 11, "found_functions": 139, "real_classes": 11, - "real_functions": 141 + "real_functions": 139 } diff --git a/tests/tree_sitter_accuracy_baseline_objective-c.json b/tests/tree_sitter_accuracy_baseline_objective-c.json index 104fc3f49..b33809c81 100644 --- a/tests/tree_sitter_accuracy_baseline_objective-c.json +++ b/tests/tree_sitter_accuracy_baseline_objective-c.json @@ -1,12 +1,12 @@ { - "args_comparable": 151, - "args_exact_match": 151, + "args_comparable": 153, + "args_exact_match": 153, "corpus_path": "language-crucible/data/objective-c", "extra_classes": 0, - "extra_functions": 3, + "extra_functions": 1, "files_scanned": 5, "found_classes": 5, - "found_functions": 151, + "found_functions": 153, "real_classes": 5, "real_functions": 153 } From 75ab06cefbe61726235461ac4f34b22c8d57b65c Mon Sep 17 00:00:00 2001 From: squid-protocol Date: Sat, 29 Aug 2026 18:31:25 -0400 Subject: [PATCH 2/4] docs(recall-audit): record the standing "is GG missing anything" answer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - tri_comparison_README.md's RECALL_AUDIT block: the complete list of genuine GitGalaxy function-recall gaps across the whole corpus (4 forms, each linked to #2459/#2460/#2461/#2462), plus a one-line note that everything else recall_audit.py prints is a catalogued tool artifact. - c.md / cpp.md / fortran.md / lua.md §9: a "Recall audit" subsection per skill step 2.6 -- the before/after recall number, "every non-detection individually assessed", and the per-mechanism bucket breakdown with file:line citations. - lua.md §5: corrected -- `constructs.lua:f` is a real gap (`local a; local function f`), not alignment fuzz; both lua misses are now #2461. Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_019Zm1uVBpVEZJ9SB7bWFR8S --- docs/language_status/c.md | 9 +++++++++ docs/language_status/cpp.md | 21 +++++++++++++++++++++ docs/language_status/fortran.md | 10 ++++++++++ docs/language_status/lua.md | 20 ++++++++++++-------- docs/self_scan/tri_comparison_README.md | 18 +++++++++++++++++- 5 files changed, 69 insertions(+), 9 deletions(-) diff --git a/docs/language_status/c.md b/docs/language_status/c.md index a873fe9a0..265f3cffe 100644 --- a/docs/language_status/c.md +++ b/docs/language_status/c.md @@ -281,6 +281,15 @@ scope caveat near the end of this section — a handful of real, independently-f args-counting bugs exist and predate this sweep; this methodology can only catch what the three tools disagree about, not a shared blind spot). Every disagreement that DID surface either resolved in GitGalaxy's favor, or turned out to be a bug in this repo's own comparison tooling + +**Recall audit (2026-08-29, skill step 2.6).** Every function tree-sitter reports that GitGalaxy +does not (6 occurrences) was individually read. **All 6 are inside `#if 0` dead blocks** — +`_PyObject_ManagedDictValidityCheck` (`cpython/dictobject.c:7396`), `print_stack` / +`print_stacks` / `tos_char` (`cpython/frameobject.c:1264`), and `PlinkPrint` / `SetPrint` +(`sqlite/lemon.c:3443`, K&R-style *and* dead). tree-sitter-c has no preprocessor model and +parses the dead branch; GitGalaxy correctly skips it (Claim 8). The accuracy audit was corrected +to drop `#if 0` / `#if false` function definitions from ground truth — **C func recall 99.7% → +100.0%**, zero real recall gaps. (found and fixed as part of the same pass) or a known tree-sitter-c/ctags limitation — never GitGalaxy's regex engine itself. Current measured numbers (`tests/tools/tri_comparison_chart.py --languages c`, `language-crucible/data/c/` — diff --git a/docs/language_status/cpp.md b/docs/language_status/cpp.md index 353cfe79d..d4b954e39 100644 --- a/docs/language_status/cpp.md +++ b/docs/language_status/cpp.md @@ -293,6 +293,27 @@ built entirely from that investigation's evidence trail, not from memory of it. |---|---|---|---|---| | cpp | ~780 (raw ledger counts, updated after the macro-shield fix) | 6 (4 filed and open, 2 filed and fixed) | 4 (fixed across two follow-up rounds) | 3 (documented, not fixable here) | +### Recall audit (2026-08-29, skill step 2.6) + +Every function tree-sitter reports that GitGalaxy does not — **164 occurrences** — was +individually read. **Cpp func recall 87.0% → 99.9%** (100% precision throughout). Bucket +breakdown: + +- **~96** — `OPCODE(m_op) { ... }` case-label bodies in `godot/gdscript_vm.cpp`'s computed-goto + bytecode table. Function-like macro invocation; tree-sitter's alone. Now in + `_CPP_KNOWN_MACRO_HALLUCINATIONS`. +- **~50** — `_FORCE_INLINE_`-macro-mangled member parses in `godot/object.h` / `variant.h`: + tree-sitter drops the `operator` keyword or `~` into an ERROR node and names the member by a + bare type (`for`, `bool`, `void`, `_value`). #2455's #1849-Phase-2 promotion + a symmetric + "don't trust tree-sitter's names inside a cpp ERROR span" drop. +- **~12** — `= default` / `= delete` special members (`mlir/flatbuffer_export.cc`, + `object.h`) — not body-bearing, GitGalaxy correctly skips. +- **~4** — `_PyObject_ManagedDictValidityCheck` etc. inside `#if 0` (also counts for `c`) — + tree-sitter has no preprocessor model (Claim 8). +- **1 real GitGalaxy recall gap** — `__control_entrypoint(DllExport) STDAPI DllCanUnloadNow()` + in `powertoys/ImageResizerExt.cpp`: a macro-supplied return type `func_start` doesn't admit. + → [#2460](https://github.com/squid-protocol/gitgalaxy/issues/2460). + Six real GitGalaxy engine defects were confirmed and filed in this sweep — more than any other language this sweep methodology has been run against so far, though that reflects C++'s syntactic complexity (templates, operator overloading, out-of-class definitions, GNU extensions in real diff --git a/docs/language_status/fortran.md b/docs/language_status/fortran.md index 682c333ce..122539393 100644 --- a/docs/language_status/fortran.md +++ b/docs/language_status/fortran.md @@ -309,6 +309,16 @@ traced to their own confirmed limitations); two were confirmed real bugs in this | Class recall/precision | **100%** (11/11) | 100% (11/11) | 100% (11/11) | fully reconciled after this pass's ctags_reader.py fix — see below | | Args found (of 123 total claimed by any tool) | **123** | 123 | 95 | tied for best; a separate, narrower per-function args-*count* defect exists independent of this existence panel — see below | +**Recall audit (2026-08-29, skill step 2.6).** Every function tree-sitter reports that GitGalaxy +does not (2 occurrences — `compute_eta`, `wrf_error_fatal`) was individually read. Both are +**phantoms tree-sitter parses from inside the `#ifdef VERT_UNIT` unit-test driver** — the +top-level `program vint` / `program foo` blocks (`module_initialize_real.F:5375` / `:7519`) that +are alternative compilation roots, dead when the file is built as a module. tree-sitter has no +preprocessor model; GitGalaxy finds both real `SUBROUTINE` definitions (lines 5471 / 7567) and +correctly ignores the driver blocks. The accuracy audit was corrected to mark a module file's +`program`…`end program` spans as blind spots — **Fortran func recall 98.6% → 100.0%**, zero real +recall gaps. + Before this pass: Functions Found showed 137*/123*/137* (all three asterisked — unvalidated), Func Precision 135/137*/123/123*/137/137*, Classes Found 11*/11*/3* (ctags badly undercounting), Args Found 121*/121*/95*. Every asterisk here is now cleared and GitGalaxy holds an outright diff --git a/docs/language_status/lua.md b/docs/language_status/lua.md index 33221980f..16a470523 100644 --- a/docs/language_status/lua.md +++ b/docs/language_status/lua.md @@ -60,12 +60,15 @@ tradeoff. ## 5. Known limitations (accepted / tracked) -- **Two low-value recall misses** (shape `agree[ctags,tree_sitter]_vs[gitgalaxy]`, 2 - occurrences). `constructs.lua:f` is an occurrence-alignment fuzz on a name defined 4× — ctags' - own false-positive `f` (from a `local f = load(...)` assignment) and a tree-sitter `f` pair to - different lines than GitGalaxy's four real ones. `literals.lua:lexerror` is a genuine single - miss inside `test/literals.lua`, the Lua suite's lexer-torture fixture (adversarial nested - `[[` / `]=]` / `\z` string data by design). Neither is worth chasing. +- **Two recall misses** (skill step 2.6 recall audit, 2026-08-29 — func recall 99.7%), both + filed as [#2461](https://github.com/squid-protocol/gitgalaxy/issues/2461): + - `constructs.lua:105` — `local a; local function f(x) ... end`. `func_start` is + start-of-line anchored, so a `local function` that is not the first statement on its line is + missed. GitGalaxy finds the other 4 `function f` in the file; this is a real, narrow gap. + - `literals.lua:80` — `local function lexerror (s, err)`, inside `test/literals.lua` (the Lua + suite's *lexer-torture fixture*, adversarial nested `[==[[===[[=[…]]=][====[…]` long + brackets that defeat `_LUA_LONG_BRACKET_RE`'s single-backref shielding). Only ever exercised + by this one fixture. - **`class_start` keeps one borderline hit** (`tracegc.lua:M` — `local M = {}` with `function M.start` / `function M.stop` / `return M`, a real module table). #2439's proto-table "tell" gate dropped the other 13 ALL_CAPS-data-table false positives; `M` is legitimately @@ -264,8 +267,9 @@ shared reason." This is the common case per the skill's step 4 guidance. heuristic matched ALL_CAPS data tables. - [#2440](https://github.com/squid-protocol/gitgalaxy/issues/2440) — **fixed**: polyglot segmentation split a function at `