fix(extract): eliminate WASM/native node divergence#1266
Conversation
Two independent root causes produced the persistent full-build node divergence between the WASM and native engines (tracked in #1263): - The native Ruby extractor never handled top-level `assignment` nodes, so program-level constants (e.g. `SKIP_CLASSES = %w[...].freeze`) were dropped while the WASM extractor extracted them. Added an `assignment` arm mirroring `handleRubyAssignment`, gated to `program`-level constant targets so class/module-body constants stay attributed to their owner. - The C++ benchmark fixture `service.h` was parsed as C (`.h` maps to C), where tree-sitter-c 0.23 (native) error-recovered `class Service {}` into a bogus `function` node while 0.24 (WASM) dropped it. The file is genuinely C++, so renamed it to `service.hpp`; both engines now parse it as C++ and agree (class/method/property nodes). Updated the `#include` lines and taught the native tracer to copy `.hpp` headers. After both fixes the full-build node sets are byte-identical across engines. The residual call-edge divergence stems from grammar-version drift between the Rust crates and npm WASM packages and is tracked separately in #1265. Closes #1263 docs check acknowledged: bug fix + test fixture rename, no language/ architecture/feature changes warranting README/CLAUDE/ROADMAP edits.
|
Claude finished @carlos-alm's task —— View job PR Review: fix(extract): eliminate WASM/native node divergenceTasks
Root Cause AnalysisProblem Being Solved: Two independent bugs caused the native engine to produce different node sets than the WASM engine for a full-repo build. Bug 1: the native Ruby extractor never handled Why This Approach: Both fixes are correct and targeted. The Ruby fix ports the existing WASM Risk Assessment: Low. Both fixes are purely additive on the extraction side — they add nodes that were previously missing, rather than removing or transforming existing ones. The Phase 1 — Root Cause Analysis: PASSBoth fixes address genuine bugs at the extraction layer, not symptoms. No warnings are being silenced. No "parity gap" is being documented as acceptable. Phase 2 — Configuration Change Detection: PASSNo configuration, lint rules, TypeScript flags, or test thresholds were modified. Zero config changes in this PR. Phase 3 — Test Integrity: PASSThree new unit tests were added directly to
All three tests target exactly the new The WASM-side tests in Phase 4 — Code QualityRuby extractor ( The implementation is a faithful, idiomatic Rust port of the TypeScript
One minor observation: C++ fixture rename
Native tracer ( The added line: cp "$FIXTURE_DIR"/*.hpp "$TMP_DIR/" 2>/dev/null || trueis inserted after the existing Minor concern — Phase 5 — Backlog Compliance
Critical ConcernsMinor gap — no WASM-side test for top-level constant extraction ( The three new unit tests live entirely in the Rust crate. The WASM extractor ( Suggestion: Consider adding Final Assessment |
Greptile SummaryThis PR eliminates the WASM/native engine node divergence (#1263) by fixing two independent root causes: adding top-level constant extraction to the native Ruby extractor and renaming a misclassified C header to
Confidence Score: 5/5Safe to merge — both fixes are narrow and well-tested, with no changes to core extraction logic for existing node kinds. The Ruby extractor change is a guarded additive path: it only fires when the assignment node is a direct child of the program root and the left-hand side is a constant, leaving class- and module-body constants untouched. The C++ fixture rename is purely mechanical — service.hpp content is byte-for-byte identical to the old service.h — and the one-line tracer addition follows the existing copy pattern exactly. Three Rust unit tests and three TypeScript tests explicitly cover the boundary conditions. No files require special attention. Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[walk_tree visits node] --> B{node.kind?}
B -->|assignment| C[handle_assignment]
B -->|class| D[handle_class]
B -->|module| E[handle_module]
B -->|method/call/etc| F[other handlers]
C --> G{parent.kind == program?}
G -->|No| H[return early]
G -->|Yes| I{left.kind == constant?}
I -->|No| J[return early]
I -->|Yes| K[push to symbols.definitions]
D --> L[extract_ruby_class_children]
Reviews (3): Last reviewed commit: "Merge branch 'main' into fix/engine-node..." | Re-trigger Greptile |
Codegraph Impact Analysis7 functions changed → 5 callers affected across 2 files
|
|
Addressed review feedback:
|
|
Claude finished @carlos-alm's task —— View job Follow-up Review: WASM-side Ruby testsTasks
AssessmentThe three new WASM-side tests in
The TS tests are slightly stricter on the positive case (also assert The minor gap from the original review is fully addressed. No new concerns. Updated rating: ⭐⭐⭐⭐⭐ (5/5) — APPROVE |
Summary
Eliminates the persistent full-build node divergence between the WASM and native engines (tracked in #1263). Two independent root causes:
assignmentnodes, so program-level constants (e.g.SKIP_CLASSES = %w[...].freeze) were dropped while the WASM extractor extracted them. Added anassignmentarm mirroringhandleRubyAssignment, gated toprogram-level constant targets so class/module-body constants stay attributed to their owner.service.hwas parsed as C (.hmaps to C), where tree-sitter-c 0.23 (native) error-recoveredclass Service {}into a bogusfunctionnode while 0.24 (WASM) dropped it. The file is genuinely C++, so it's renamed toservice.hpp— both engines now parse it as C++ and agree (class/method/property nodes). Updated the#includelines and taught the native tracer to copy.hppheaders.After both fixes, the full-build node sets are byte-identical across engines.
Out of scope (tracked separately)
The residual ~30–46 call-edge divergence stems from grammar-version drift between the Rust crates and the npm WASM packages (e.g. go 0.23↔0.25, python 0.23↔0.25, c 0.23↔0.24). That is a large, multi-language alignment effort and is tracked in #1265.
Test plan
cargo test --lib— 327 pass, including the grammar-ABI regression test and 3 new Ruby extractor testsCloses #1263