From cd8eb4757c5c8075e02fc04e342547ecb4ac5166 Mon Sep 17 00:00:00 2001 From: Gergo Magyar Date: Wed, 3 Jun 2026 07:48:45 +0000 Subject: [PATCH] test(ingestion): rebaseline #1982 golden/fingerprint + lint/format sweep MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cross-cutting verification artifacts for the #1982 same-tail resolution fix: - ruby capture golden regenerated: ONLY the ruby-nested-tail-collision fixture drifts (+10 capture groups from its new include/attr_accessor + the now full-qualified __heritage__/__property__ marker owner). All other ruby fixtures byte-identical (proves the owner-qualification is localized to nested owners). - bench/scope-capture/baselines.json: rebaseline cpp + ruby fingerprints (the only two that drift; 12 other languages byte-identical). cpp = additive @reference.qualified-name capture; ruby = the localized owner change. Provenance notes record both. scaling linear (~1.0), 14/14 PASS. - generic.ts: drop the now-unused normalizeQualifiedName import (lint error). - walkers.ts / ruby.test.ts: prettier formatting. Verified: cpp 278/278 + ruby 142/142 (registry-primary), both legacy legs clean (skips registry-primary-only assertions), go/java/csharp 542 (cross-language regression — the qualified-first branch is gated on rawQualifiedName, set only by C++, so non-C++ inheritance resolution is unchanged). tsc + eslint(0 errors) + prettier clean. Co-Authored-By: Claude Opus 4.8 (1M context) --- gitnexus/bench/scope-capture/baselines.json | 8 +- .../ingestion/class-extractors/generic.ts | 2 +- .../scope-resolution/scope/walkers.ts | 5 +- .../expected-captures.json | 4 +- .../test/integration/resolvers/ruby.test.ts | 89 +++++++++++-------- 5 files changed, 59 insertions(+), 49 deletions(-) diff --git a/gitnexus/bench/scope-capture/baselines.json b/gitnexus/bench/scope-capture/baselines.json index ca5cdb99e..4944d7b94 100644 --- a/gitnexus/bench/scope-capture/baselines.json +++ b/gitnexus/bench/scope-capture/baselines.json @@ -16,11 +16,11 @@ "_added": "#1956: c added to the scope-capture bench (was UNBENCHED). C has no inheritance \u2014 flat scale source. Adding it exposed + fixed a pre-existing O(n^2) findNodeAtRange root-walk in c/captures.ts (threaded c.node, byte-identical over c-* fixtures); scaling 3.475 -> 0.96." }, "cpp": { - "fingerprint": "a59156a63f89364fde16e2c6c238f696fc9e66328c49e5b235ac88b662d279b3", + "fingerprint": "2f517381e8b03db221d13f65d5e485d021c17a2f7fa684446e09f33d78c3adb9", "scaling_budget": 1.5, "_added": "#1956: cpp added to the scope-capture bench (was UNBENCHED). Heritage-bearing scale source (: public Base, public Mixin) drives emitCppInheritanceCaptures at scale. Adding it exposed + fixed a pre-existing O(n^2) findNodeAtRange root-walk in cpp/captures.ts (~12 sites, threaded c.node, byte-identical over 263 cpp-* fixtures); scaling 2.30 -> 1.12.", "_rebaselined": "#1965 / #1923 F4: uninitialized non-leading multi-declarators now emit @declaration.variable captures; cpp-adl-inner-callable-outer-noncallable data::Pair a, b adds the legitimate fixture drift. Linear (~1.06).", - "_note": "#1975: + cpp-out-of-line-class fixture (out-of-line struct Outer::Inner / Other::Inner). Pure fixture-corpus drift — the fix is the legacy structure-query qualified_identifier arm, NOT the cpp scope-extractor; existing fixtures' captures byte-identical. fixture_count 263->265." + "_note": "#1975: + cpp-out-of-line-class fixture (out-of-line struct Outer::Inner / Other::Inner). Pure fixture-corpus drift — the fix is the legacy structure-query qualified_identifier arm, NOT the cpp scope-extractor; existing fixtures' captures byte-identical. fixture_count 263->265. #1982: cpp-nested-tail-collision gains qualified heritage (struct DerivedA : Outer::Inner, struct DerivedB : Other::Inner) AND emitCppInheritanceCaptures now emits an ADDITIVE @reference.qualified-name capture on QUALIFIED bases (drives the qualified-first inheritance resolver). Purely additive — existing captures unchanged; same fixture file, no new fixture." }, "csharp": { "_rebaselined": "#1956 synth-widening: + csharp-qualified-base fixture; the synth now walks record_declaration + struct_declaration base_lists and handles alias_qualified_name (matching the #1940 legacy leg), so record/struct heritage now emits. csharp-record-base gains a record inherits capture. (record->record SAME-namespace EXTENDS is a separate registry resolution gap, tracked as follow-up.) Linear (~1.00). (Earlier #1956: heritage-bearing scale source.)", @@ -39,10 +39,10 @@ "_rebaselined": "#1956: heritage-bearing scale source (class extends Base + use trait); both forms gated at scale; linear (~1.04)." }, "ruby": { - "fingerprint": "17782d4a8697f7bd80a25075bebec8ba97c6717b8014ce5b1fb8548a4073e1c8", + "fingerprint": "011c0533318ff61d99267d501866af8a616b1c212050628339064d8c149aafbf", "scaling_budget": 1.5, "_rebaselined": "#1956 synth-widening: + ruby-qualified-base fixture; synth now reduces a scope_resolution superclass (class C < Mod::Super) to its trailing constant (matching the #1940 legacy leg), at parity. Linear (~1.03). (Earlier #1956: heritage-bearing scale source.)", - "_note": "F62: + scope_resolution class/module declaration captures — fixture count 78→81, fingerprint drift expected. #1975: + ruby-tail-collision fixture (Foo::Bar vs Baz::Bar stay distinct nodes) — pure fixture-corpus drift, scope-extractor captures unchanged; 81→82. #1978: + ruby-nested-tail-collision (same-tail Inner under Outer/Other modules + Shapes.Circle attr_accessor) — pure fixture-corpus drift, scope-extractor captures unchanged; 82→83." + "_note": "F62: + scope_resolution class/module declaration captures — fixture count 78→81, fingerprint drift expected. #1975: + ruby-tail-collision fixture (Foo::Bar vs Baz::Bar stay distinct nodes) — pure fixture-corpus drift, scope-extractor captures unchanged; 81→82. #1978: + ruby-nested-tail-collision (same-tail Inner under Outer/Other modules + Shapes.Circle attr_accessor) — pure fixture-corpus drift, scope-extractor captures unchanged; 82→83. #1982: that fixture gains same-tail include + attr_accessor, AND emitRubyScopeCaptures now emits the FULL qualified owner in __heritage__/__property__ markers (buildEnclosingQualifiedName) — a CODE change LOCALIZED to nested owners: the golden shows ONLY this fixture drifts (+10 capture groups), all other ruby fixtures byte-identical, and 142/142 resolver tests pass. fixture_count 83 (same file)." }, "swift": { "fingerprint": "53325c6345161c5a495f997297af5a24fb718fd3e6647040160f8ab2a2c8e4c0", diff --git a/gitnexus/src/core/ingestion/class-extractors/generic.ts b/gitnexus/src/core/ingestion/class-extractors/generic.ts index 7ed86a934..6cfc7a3c0 100644 --- a/gitnexus/src/core/ingestion/class-extractors/generic.ts +++ b/gitnexus/src/core/ingestion/class-extractors/generic.ts @@ -6,7 +6,7 @@ import type { ClassLikeNodeLabel, ExtractedClassSymbol, } from '../class-types.js'; -import { normalizeQualifiedName, splitQualifiedName } from '../utils/qualified-name.js'; +import { splitQualifiedName } from '../utils/qualified-name.js'; const DEFAULT_SCOPE_NAME_NODE_TYPES = new Set([ 'nested_namespace_specifier', diff --git a/gitnexus/src/core/ingestion/scope-resolution/scope/walkers.ts b/gitnexus/src/core/ingestion/scope-resolution/scope/walkers.ts index 41c531f09..29fe2b8ac 100644 --- a/gitnexus/src/core/ingestion/scope-resolution/scope/walkers.ts +++ b/gitnexus/src/core/ingestion/scope-resolution/scope/walkers.ts @@ -381,10 +381,7 @@ function resolveQualifiedInheritanceBase( * `NS.Other.Derived` this is `['NS', 'Other']`; empty for a file-scope child. * Used to build progressive-prefix lookup keys for relative qualified bases. */ -function enclosingScopeSegments( - startScope: ScopeId, - scopes: ScopeResolutionIndexes, -): string[] { +function enclosingScopeSegments(startScope: ScopeId, scopes: ScopeResolutionIndexes): string[] { const child = findEnclosingClassDef(startScope, scopes); const q = child?.qualifiedName; if (q === undefined || q.length === 0) return []; diff --git a/gitnexus/test/fixtures/ruby-captures-golden/expected-captures.json b/gitnexus/test/fixtures/ruby-captures-golden/expected-captures.json index 2f0399819..fb838f769 100644 --- a/gitnexus/test/fixtures/ruby-captures-golden/expected-captures.json +++ b/gitnexus/test/fixtures/ruby-captures-golden/expected-captures.json @@ -208,8 +208,8 @@ "digest": "34e07387fece6c1d2deb49c39fc2bfe0badfe8015dd1f7ae956d57ac98322a1d" }, "ruby-nested-tail-collision/nested.rb": { - "captureGroups": 21, - "digest": "48a7c1268b9542cf6d1eed5f6bd5dd68964cc608eb7f73953811d7f29ec35917" + "captureGroups": 31, + "digest": "c48ebe5516a0faf50effbad0a19fe29be70c371b50ba9d6fa6ae3f6f708b3a4e" }, "ruby-overload-dispatch/lib/app.rb": { "captureGroups": 10, diff --git a/gitnexus/test/integration/resolvers/ruby.test.ts b/gitnexus/test/integration/resolvers/ruby.test.ts index c325a1381..e79d2134e 100644 --- a/gitnexus/test/integration/resolvers/ruby.test.ts +++ b/gitnexus/test/integration/resolvers/ruby.test.ts @@ -1569,30 +1569,36 @@ describe('Ruby inline module-nested same-tail collision — distinct nodes (issu // so outer_attr / other_attr both attach to whichever `Inner` was processed // last. Asserts each routes to its OWN qualified node by qualifiedName, with // exactly one (non-duplicated) edge. Registry-primary only. - pit('owns outer_attr / other_attr under their OWN qualified Inner node (same-tail attr_accessor, R7)', () => { - const hp = getRelationships(result, 'HAS_PROPERTY'); - const ownerQnOf = (prop: string) => { - const e = hp.find((x) => x.target === prop); - expect(e, `HAS_PROPERTY -> ${prop}`).toBeDefined(); - return result.graph.getNode(e!.rel.sourceId)?.properties.qualifiedName; - }; - expect(ownerQnOf('outer_attr')).toBe('Outer.Inner'); - expect(ownerQnOf('other_attr')).toBe('Other.Inner'); - expect(hp.filter((x) => x.target === 'outer_attr')).toHaveLength(1); - expect(hp.filter((x) => x.target === 'other_attr')).toHaveLength(1); - }); + pit( + 'owns outer_attr / other_attr under their OWN qualified Inner node (same-tail attr_accessor, R7)', + () => { + const hp = getRelationships(result, 'HAS_PROPERTY'); + const ownerQnOf = (prop: string) => { + const e = hp.find((x) => x.target === prop); + expect(e, `HAS_PROPERTY -> ${prop}`).toBeDefined(); + return result.graph.getNode(e!.rel.sourceId)?.properties.qualifiedName; + }; + expect(ownerQnOf('outer_attr')).toBe('Outer.Inner'); + expect(ownerQnOf('other_attr')).toBe('Other.Inner'); + expect(hp.filter((x) => x.target === 'outer_attr')).toHaveLength(1); + expect(hp.filter((x) => x.target === 'other_attr')).toHaveLength(1); + }, + ); // #1982 resolution-side: SAME-TAIL mixin owner identity (IMPLEMENTS). - pit('routes include OuterMix / OtherMix to their OWN qualified Inner owner (same-tail mixin, R7)', () => { - const impl = getRelationships(result, 'IMPLEMENTS'); - const ownerQnOfMixin = (mixinName: string) => { - const e = impl.find((x) => x.target === mixinName); - expect(e, `IMPLEMENTS -> ${mixinName}`).toBeDefined(); - return result.graph.getNode(e!.rel.sourceId)?.properties.qualifiedName; - }; - expect(ownerQnOfMixin('OuterMix')).toBe('Outer.Inner'); - expect(ownerQnOfMixin('OtherMix')).toBe('Other.Inner'); - }); + pit( + 'routes include OuterMix / OtherMix to their OWN qualified Inner owner (same-tail mixin, R7)', + () => { + const impl = getRelationships(result, 'IMPLEMENTS'); + const ownerQnOfMixin = (mixinName: string) => { + const e = impl.find((x) => x.target === mixinName); + expect(e, `IMPLEMENTS -> ${mixinName}`).toBeDefined(); + return result.graph.getNode(e!.rel.sourceId)?.properties.qualifiedName; + }; + expect(ownerQnOfMixin('OuterMix')).toBe('Outer.Inner'); + expect(ownerQnOfMixin('OtherMix')).toBe('Other.Inner'); + }, + ); }); // Same fixture through the WORKER pool. The deferred note flagged that the worker @@ -1604,26 +1610,33 @@ describe('Ruby inline module-nested same-tail collision — worker path parity ( let result: PipelineResult; beforeAll(async () => { - result = await runPipelineFromRepo(path.join(FIXTURES, 'ruby-nested-tail-collision'), () => {}, { - workerThresholdsForTest: { minFiles: 1, minBytes: 1 }, - workerPoolSize: 2, - }); + result = await runPipelineFromRepo( + path.join(FIXTURES, 'ruby-nested-tail-collision'), + () => {}, + { + workerThresholdsForTest: { minFiles: 1, minBytes: 1 }, + workerPoolSize: 2, + }, + ); }, 120000); pit('genuinely used the worker pool for the same-tail Ruby fixture', () => { expect(result.usedWorkerPool).toBe(true); }); - pit('owns outer_attr / other_attr under their OWN qualified Inner node on the worker path (no duplicate, R7)', () => { - const hp = getRelationships(result, 'HAS_PROPERTY'); - const ownerQnOf = (prop: string) => { - const e = hp.find((x) => x.target === prop); - expect(e, `HAS_PROPERTY -> ${prop}`).toBeDefined(); - return result.graph.getNode(e!.rel.sourceId)?.properties.qualifiedName; - }; - expect(ownerQnOf('outer_attr')).toBe('Outer.Inner'); - expect(ownerQnOf('other_attr')).toBe('Other.Inner'); - expect(hp.filter((x) => x.target === 'outer_attr')).toHaveLength(1); - expect(hp.filter((x) => x.target === 'other_attr')).toHaveLength(1); - }); + pit( + 'owns outer_attr / other_attr under their OWN qualified Inner node on the worker path (no duplicate, R7)', + () => { + const hp = getRelationships(result, 'HAS_PROPERTY'); + const ownerQnOf = (prop: string) => { + const e = hp.find((x) => x.target === prop); + expect(e, `HAS_PROPERTY -> ${prop}`).toBeDefined(); + return result.graph.getNode(e!.rel.sourceId)?.properties.qualifiedName; + }; + expect(ownerQnOf('outer_attr')).toBe('Outer.Inner'); + expect(ownerQnOf('other_attr')).toBe('Other.Inner'); + expect(hp.filter((x) => x.target === 'outer_attr')).toHaveLength(1); + expect(hp.filter((x) => x.target === 'other_attr')).toHaveLength(1); + }, + ); });