Repository navigation
fix(zig): wire zig into class_start named-entity extraction - #1367
Merged
Merged
Conversation
Two fixes, plus a documented set of ground-truth-vs-regex scope gaps (same discipline as csharp/go's precedent in #1264): 1. Ground-truth gap: zig's error sets (`const Foo = error{...};`) get their own `ErrorSetDecl` node type, distinct from `ContainerDecl` -- a real class-like entity GitGalaxy's own class_start regex intentionally matches (its own comment: "struct, enum, union, error, opaque"), but NODE_MAPS["zig"] didn't include it. Added, dispatched through the same _get_zig_container_name resolver ContainerDecl already uses. This alone dropped extra_classes from 10 -> 1. 2. class_start regex gap: an optional `\(` and `\*` step-over added between `=` and the packed/extern modifier, confirmed against two real corpus idioms -- a parenthesized-wrapped anonymous struct (`const lenAsc = (struct { ... }).lenAsc;`) and a pointer-to-opaque handle type (`const HMONITOR = *opaque {};`, the standard idiom for an opaque OS handle). The remaining extra_classes=1 ("Borrowed" in bun/MimallocArena.zig) is a confirmed tree-sitter-zig grammar limitation: the file uses Zig's newer `#field` private-field syntax, which the grammar can't parse (has_error=True on that node), so error recovery swallows the container declaration -- the same shape as csharp's LanguageParser precedent in #1264. Hand-blessed tests/tree_sitter_accuracy_baseline_zig.json to the measured numbers (found_classes 0->630, real_classes 642->656, extra_classes 0->1) since --regenerate correctly refuses on a raw extra_classes regression and this one isn't a GitGalaxy bug. missing_classes (23->26, net of the 2 regex fixes minus 5 newly-exposed-by -the-ErrorSetDecl-fix compound error-union-chain cases) stays non-zero by design -- documented per-category in tests/extraction/how_to_extend_class_start_named_extraction.md rather than chased in this PR: compound error-set unions (`A || B || error{C}`), if/else conditional anonymous types, type-annotation-position anonymous types (`var x: enum {...} = ...`), and anonymous structs nested inside a generic call argument or array-element type (tree-sitter's ancestor walk finding them regardless of whether they're the direct declared value). zig added to detector.py's _CLASS_START_NAMED_EXTRACTION_LANGS allowlist. Golden master updated (both modes): comptime_string_map.zig's class count 6->7 (the parenthesized-struct fix) and win32.zig's 158->159 (the pointer-to-opaque fix) -- both intentional, all other diffs are downstream numeric fallout of those two signal changes. Verified: crucible_check.py (both modes) clean after regenerating the golden master, core_engine/extraction suite (6584 tests) passes, audit_check.py clean (ruff baseline regenerated, pure line-shifts only). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Move zig from "ground truth already works" to "done", record the ErrorSetDecl ground-truth fix, the paren/pointer-sigil regex widening, and the confirmed tree-sitter parse-error edge case. New recurring-cause class 7 documents the four scope-mismatch shapes found but not chased (nested-in-generic-call, nested-in-array-element-type, type-annotation position, and binary error-set-union chains) so a future pass has the categorization ready instead of re-deriving it. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Contributor
4 tasks done
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Extends #1264's per-language
class_startnamed-entity extraction to Zig, per epic #1295's checklist. Zig is the biggest/messiest language in this exercise so far (32 corpus files,real_classesin the hundreds), and the first to land withextra_classes/missing_classesstill non-zero by design after investigation -- following the same discipline csharp's enum precedent in #1264 established (document real scope mismatches, don't chase every last case into one PR).tests/tools/tree_sitter_accuracy_audit.py: ground-truth gap -- zig's error sets (const Foo = error{...};) get their ownErrorSetDeclnode type, distinct fromContainerDecl, whichNODE_MAPS["zig"]didn't include. GitGalaxy's ownclass_startregex intentionally matches error sets (its own comment says "Defines structural entities: struct, enum, union, error, opaque"). AddedErrorSetDecl, dispatched through the same_get_zig_container_nameresolverContainerDeclalready uses. This alone droppedextra_classesfrom 10 to 1.gitgalaxy/standards/language_standards.py:class_startwidened with an optional\(/\*step-over between=and the packed/extern modifier, confirmed against two real corpus idioms: a parenthesized-wrapped anonymous struct (const lenAsc = (struct { ... }).lenAsc;) and a pointer-to-opaque handle type (const HMONITOR = *opaque {};, the standard idiom for an opaque OS handle).The remaining extra_classes=1
Borrowedinbun/MimallocArena.zigis a confirmed tree-sitter-zig grammar limitation, not a GitGalaxy bug: the file uses Zig's newer#fieldprivate-field syntax, which the grammar can't parse (has_error=Trueon that node), so error recovery swallows the container declaration. Same shape as csharp'sLanguageParserprecedent in #1264.--regeneratecorrectly refuses when it sees a rawextra_classesregression (0→1), even thoughfound_classesimproved from 0 to 630 in the same run. Per the doc's own documented escape hatch for this exact situation, I hand-blessedtests/tree_sitter_accuracy_baseline_zig.jsonto the measured numbers and explained why here, same as csharp's precedent.missing_classes stays non-zero by design
found_classes0→630 out ofreal_classes642→656 (grew because theErrorSetDeclfix exposed more real declarations). Themissing_classesset (23→26 net) breaks down into four understood-but-not-chased shapes, written up as a new recurring-cause class in the checklist doc:const Extra = List(struct { u32 });) -- not the direct declared value.const targets = [_]struct {...}{...};).var op: enum {...} = .example;) -- recurred 6x in the corpus, the most promising follow-up candidate.const X = A || B || error{C};) -- would need meaningfully more regex complexity to skip safely.None of these are GitGalaxy bugs or ground-truth bugs -- they're legitimate scope boundaries worth a dedicated follow-up decision rather than folding into this PR.
Result
found_classes0→630,real_classes642→656,extra_classes0→1 (documented, not a bug).zigadded todetector.py's_CLASS_START_NAMED_EXTRACTION_LANGS.Golden master updated (both modes):
bun/comptime_string_map.zig's class count 6→7 (the parenthesized-struct fix) andzls/mach/win32.zig's 158→159 (the pointer-to-opaque fix) -- both intentional, all other diffs are downstream numeric fallout of those two signal changes.Test plan
python tests/tools/class_start_diff.py --lang zig-- iterated until only the one confirmed tree-sitter parse-error case remained "extra"python tests/tools/tree_sitter_accuracy_audit.py --lang zig --ci/ hand-blessed baseline after--regeneratecorrectly refused on the documented non-bug regressionpython tests/tools/tree_sitter_accuracy_audit.py --summary-tablepython tests/tools/update_golden_master.py --yesin both.crucible_venvs/{full_precision,zero_dependency}(confirmed each venv's editable install resolves to this checkout first)python tests/tools/crucible_check.py(both modes) -- clean, zero diff after regeneratingpython -m pytest tests/core_engine/ tests/extraction/-- 6584 passed, 2 skipped, 11 xfailed, 3 xpassedpython tests/tools/audit_check.py --regenerate-- ruff baseline regenerated (pure line-shifts from the new comment block only), mypy/dead-key/ast-accuracy all clean🤖 Generated with Claude Code