Skip to content

Epic: Real-world tree-sitter/AST accuracy tracking, per language #1227

Description

@squid-protocol

Why

docs/language_status/<lang>.md §9 ("Measured accuracy") is the strongest evidence this repo
has for whether func_start/args/class_start/_dependency_capture actually work on real,
unmodified production code -- as opposed to the (also necessary, but isolated) hand-picked
valid/invalid/pathological snippets in tests/extraction/languages/test_<lang>.py. It's the
methodology that surfaced #1182/#1183/#1184/#1193 for Python (via stdlib ast) and #1220/#1221/
#1222 for JavaScript (via tree-sitter-language-pack, the first non-Python repeat).

Both of those passes were one-off, hand-run investigations -- the JavaScript one explicitly used
an ad hoc scratchpad script, not committed tooling (see PR #1223's own description: "no committed
permanent tooling ... since the user chose 'single deep dive' not 'build the tooling'"). That
means every future language pass currently re-derives the methodology from scratch, and there's
no regression floor once a pass is done -- a later PR could silently regress a language's
real-world accuracy with nothing catching it (unlike ruff_audit.py/mypy_audit.py/
dead_key_audit.py/tests/ast_accuracy_audit.py, which are all baseline-gated).

This epic is the "build it once, then roll out per language" pass for tree-sitter-based accuracy
measurement, following the same shape as epic #813 (extraction gauntlets) and epic #1069
(strict-signature depth): one prerequisite tool-build issue, then one issue per language.

Design (from investigation, see sub-issue #1 for the full writeup)

  • One generalized script, tests/tools/tree_sitter_accuracy_audit.py, mirroring
    tests/ast_accuracy_audit.py's proven shape (pinned corpus, --ci/--regenerate/full-report
    modes, per-language baseline JSON, regression-gated not zero-tolerance) -- swap ast for
    tree-sitter-language-pack and use a small per-language "node map" (function/class node types,
    name/params field names -- these genuinely vary per grammar, e.g. JS arrow functions use field
    parameter singular for a bare param but parameters plural for a parenthesized list) as the
    only hand-built per-language artifact.
  • Corpus: reuse language-crucible (the same ~80-repo corpus tests/tools/crucible_check.py
    already diffs against, pinned at tag v1.0, resolved via LANGUAGE_CRUCIBLE_PATH or a sibling
    checkout) instead of cloning a fresh external repo per language the way the JavaScript pass did
    with expressjs/express. Confirmed via spot-check: language-crucible's files are real,
    complete, production source (not fragments -- e.g. jquery/ajax.js, Spring Boot's 1876-line
    SpringApplication.java) and tree-sitter parses them cleanly (zero has_error on the JS
    sample). This avoids building a whole new corpus-pinning/caching mechanism per language.
  • Language coverage: of GitGalaxy's 45 signature-bearing languages (has a non-None
    func_start rule), 36 have a confirmed tree-sitter-language-pack grammar (33 direct name
    matches + shell->bash, objective-c->objc, makefile->make aliases). Note this
    contradicts docs/language_status/README.md's / the language-status skill's blanket claim
    that cobol/fortran/apex/matlab have no practical ground truth -- those grammars exist in the
    pack, but may still be low-quality for real enterprise dialects and need a per-language quality
    spot-check before being trusted, not just an availability check. embedded_python, m4,
    sqlite, yacc have no tree-sitter grammar at all (9 languages, matching the skill's existing
    "no practical ground truth" list minus the 4 above, stay undocumented for §9 as already
    established).
  • Write-up location unchanged: docs/language_status/<lang>.md §9, per the existing
    language-status skill structure -- this epic doesn't change where results live, only how
    they're produced and whether they're regression-gated afterward.

Distinct from #1096

#1096 (deferred, open) proposes a hand-authored synthetic multi-language control corpus to test
whether the same construct (a for loop, a try/except) is counted equivalently across
languages -- a signal-equivalence check. This epic is about real-world extraction accuracy for
one language at a time against that language's own tree-sitter ground truth. Complementary, not
overlapping -- keep them separate.

Sequencing

  1. Build the generalized tool + node-map registry (see sub-issue -- being filed alongside this
    epic).
  2. Re-derive the JavaScript §9 numbers (fix(core): critical-leak synthetic risk_vector hardcoded to stale 18-length RISK_SCHEMA #1220/func_start missing the args regex's 'Invocation Shield': bare call statements false-positive as function definitions (7 languages) #1221/javascript: second occurrence of a structurally-identical top-level function silently dropped from function_data #1222) through the new tool as a correctness
    check before trusting it for a new language.
  3. Roll out one language at a time via its own sub-issue, filed incrementally as capacity allows
    -- not filing the full ~34 remaining candidate-language sub-issues up front (unlike Epic: Harden the four extraction gauntlets (function/args/class/dependency) per language #813/Epic: Harden the strict structural-signature test suite (non-extraction-pillar rules) per language #1069,
    which did front-load their full sub-issue list; deliberately deferred here since each pass
    costs real investigation time/tokens per language, same reasoning Feature: multi-language control corpus to validate structural extraction equivalence across languages #1096 itself gave for
    needing "a design pass before scoping into sub-issues").

Python (ast, not tree-sitter -- no grammar needed) and JavaScript (tree-sitter, ad hoc) are
already done; not re-listed as pending.

Metadata

Metadata

Assignees

No one assigned

    Labels

    core-engineModifications to the central physics and parsing engineepicLarge-scale architectural milestone or multi-issue initiativetestingUnit, integration, and E2E pipeline verification

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions