test(ingestion): rebaseline #1982 golden/fingerprint + lint/format sweep

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) <noreply@anthropic.com>
This commit is contained in:
Gergo Magyar 2026-06-03 07:48:45 +00:00
parent bb84ccb27e
commit cd8eb4757c
5 changed files with 59 additions and 49 deletions

View file

@ -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",

View file

@ -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',

View file

@ -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 [];

View file

@ -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,

View file

@ -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);
},
);
});