gitnexus 1.6.3-rc.2 → 1.6.3-rc.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -6,10 +6,14 @@ export { getLanguageFromFilename, getSyntaxLanguageFromFilename } from './langua
6
6
  export type { MroStrategy } from './mro-strategy.js';
7
7
  export type { PipelinePhase, PipelineProgress } from './pipeline.js';
8
8
  export type { SymbolDefinition } from './scope-resolution/symbol-definition.js';
9
- export type { ScopeId, DefId, ScopeKind, Range, Capture, BindingRef, ImportEdge, TypeRef, Scope, ResolutionEvidence, Resolution, Reference, ReferenceIndex, LookupParams, RegistryContributor, } from './scope-resolution/types.js';
9
+ export type { ScopeId, DefId, ScopeKind, Range, Capture, CaptureMatch, BindingRef, ImportEdge, TypeRef, Scope, ResolutionEvidence, Resolution, Reference, ReferenceIndex, LookupParams, RegistryContributor, ParsedImport, ParsedTypeBinding, WorkspaceIndex, ScopeTree, Callsite, } from './scope-resolution/types.js';
10
10
  export { EvidenceWeights, typeBindingWeightAtDepth } from './scope-resolution/evidence-weights.js';
11
11
  export { ORIGIN_PRIORITY } from './scope-resolution/origin-priority.js';
12
12
  export type { OriginForTieBreak } from './scope-resolution/origin-priority.js';
13
13
  export { LanguageClassifications, isProductionLanguage, } from './scope-resolution/language-classification.js';
14
14
  export type { LanguageClassification } from './scope-resolution/language-classification.js';
15
+ export { diffResolutions } from './scope-resolution/shadow/diff.js';
16
+ export type { ShadowAgreement, ShadowCallsite, ShadowDiff, } from './scope-resolution/shadow/diff.js';
17
+ export { aggregateDiffs } from './scope-resolution/shadow/aggregate.js';
18
+ export type { LanguageParityRow, ShadowParityReport } from './scope-resolution/shadow/aggregate.js';
15
19
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,YAAY,EACV,SAAS,EACT,cAAc,EACd,gBAAgB,EAChB,SAAS,EACT,iBAAiB,GAClB,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EACL,WAAW,EACX,cAAc,EACd,SAAS,EACT,oBAAoB,GACrB,MAAM,4BAA4B,CAAC;AACpC,YAAY,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,4BAA4B,CAAC;AAGzE,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,EAAE,uBAAuB,EAAE,6BAA6B,EAAE,MAAM,yBAAyB,CAAC;AACjG,YAAY,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGrD,YAAY,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAIrE,YAAY,EAAE,gBAAgB,EAAE,MAAM,yCAAyC,CAAC;AAChF,YAAY,EACV,OAAO,EACP,KAAK,EACL,SAAS,EACT,KAAK,EACL,OAAO,EACP,UAAU,EACV,UAAU,EACV,OAAO,EACP,KAAK,EACL,kBAAkB,EAClB,UAAU,EACV,SAAS,EACT,cAAc,EACd,YAAY,EACZ,mBAAmB,GACpB,MAAM,6BAA6B,CAAC;AAGrC,OAAO,EAAE,eAAe,EAAE,wBAAwB,EAAE,MAAM,wCAAwC,CAAC;AACnG,OAAO,EAAE,eAAe,EAAE,MAAM,uCAAuC,CAAC;AACxE,YAAY,EAAE,iBAAiB,EAAE,MAAM,uCAAuC,CAAC;AAG/E,OAAO,EACL,uBAAuB,EACvB,oBAAoB,GACrB,MAAM,+CAA+C,CAAC;AACvD,YAAY,EAAE,sBAAsB,EAAE,MAAM,+CAA+C,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,YAAY,EACV,SAAS,EACT,cAAc,EACd,gBAAgB,EAChB,SAAS,EACT,iBAAiB,GAClB,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EACL,WAAW,EACX,cAAc,EACd,SAAS,EACT,oBAAoB,GACrB,MAAM,4BAA4B,CAAC;AACpC,YAAY,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,4BAA4B,CAAC;AAGzE,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,EAAE,uBAAuB,EAAE,6BAA6B,EAAE,MAAM,yBAAyB,CAAC;AACjG,YAAY,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGrD,YAAY,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAIrE,YAAY,EAAE,gBAAgB,EAAE,MAAM,yCAAyC,CAAC;AAChF,YAAY,EACV,OAAO,EACP,KAAK,EACL,SAAS,EACT,KAAK,EACL,OAAO,EACP,YAAY,EACZ,UAAU,EACV,UAAU,EACV,OAAO,EACP,KAAK,EACL,kBAAkB,EAClB,UAAU,EACV,SAAS,EACT,cAAc,EACd,YAAY,EACZ,mBAAmB,EACnB,YAAY,EACZ,iBAAiB,EACjB,cAAc,EACd,SAAS,EACT,QAAQ,GACT,MAAM,6BAA6B,CAAC;AAGrC,OAAO,EAAE,eAAe,EAAE,wBAAwB,EAAE,MAAM,wCAAwC,CAAC;AACnG,OAAO,EAAE,eAAe,EAAE,MAAM,uCAAuC,CAAC;AACxE,YAAY,EAAE,iBAAiB,EAAE,MAAM,uCAAuC,CAAC;AAG/E,OAAO,EACL,uBAAuB,EACvB,oBAAoB,GACrB,MAAM,+CAA+C,CAAC;AACvD,YAAY,EAAE,sBAAsB,EAAE,MAAM,+CAA+C,CAAC;AAG5F,OAAO,EAAE,eAAe,EAAE,MAAM,mCAAmC,CAAC;AACpE,YAAY,EACV,eAAe,EACf,cAAc,EACd,UAAU,GACX,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EAAE,cAAc,EAAE,MAAM,wCAAwC,CAAC;AACxE,YAAY,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,wCAAwC,CAAC"}
@@ -8,4 +8,7 @@ export { EvidenceWeights, typeBindingWeightAtDepth } from './scope-resolution/ev
8
8
  export { ORIGIN_PRIORITY } from './scope-resolution/origin-priority.js';
9
9
  // Language classification (RFC §6.1 Ring 3/4 governance)
10
10
  export { LanguageClassifications, isProductionLanguage, } from './scope-resolution/language-classification.js';
11
+ // Shadow-mode diff + aggregation (RFC §6.3; Ring 2 SHARED #918)
12
+ export { diffResolutions } from './scope-resolution/shadow/diff.js';
13
+ export { aggregateDiffs } from './scope-resolution/shadow/aggregate.js';
11
14
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AASA,mBAAmB;AACnB,OAAO,EACL,WAAW,EACX,cAAc,EACd,SAAS,EACT,oBAAoB,GACrB,MAAM,4BAA4B,CAAC;AAGpC,mBAAmB;AACnB,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,EAAE,uBAAuB,EAAE,6BAA6B,EAAE,MAAM,yBAAyB,CAAC;AA2BjG,8DAA8D;AAC9D,OAAO,EAAE,eAAe,EAAE,wBAAwB,EAAE,MAAM,wCAAwC,CAAC;AACnG,OAAO,EAAE,eAAe,EAAE,MAAM,uCAAuC,CAAC;AAGxE,yDAAyD;AACzD,OAAO,EACL,uBAAuB,EACvB,oBAAoB,GACrB,MAAM,+CAA+C,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AASA,mBAAmB;AACnB,OAAO,EACL,WAAW,EACX,cAAc,EACd,SAAS,EACT,oBAAoB,GACrB,MAAM,4BAA4B,CAAC;AAGpC,mBAAmB;AACnB,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,EAAE,uBAAuB,EAAE,6BAA6B,EAAE,MAAM,yBAAyB,CAAC;AAiCjG,8DAA8D;AAC9D,OAAO,EAAE,eAAe,EAAE,wBAAwB,EAAE,MAAM,wCAAwC,CAAC;AACnG,OAAO,EAAE,eAAe,EAAE,MAAM,uCAAuC,CAAC;AAGxE,yDAAyD;AACzD,OAAO,EACL,uBAAuB,EACvB,oBAAoB,GACrB,MAAM,+CAA+C,CAAC;AAGvD,gEAAgE;AAChE,OAAO,EAAE,eAAe,EAAE,MAAM,mCAAmC,CAAC;AAMpE,OAAO,EAAE,cAAc,EAAE,MAAM,wCAAwC,CAAC"}
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Shadow-mode aggregation — per-language parity %, per-evidence-kind
3
+ * breakdown of divergences. Consumed by the parity dashboard (RING2-PKG-5).
4
+ *
5
+ * Pure functions; no I/O. The harness persists per-run JSON; the dashboard
6
+ * reads `.gitnexus/shadow-parity/latest.json` and renders.
7
+ *
8
+ * Part of RFC #909 Ring 2 SHARED — #918.
9
+ */
10
+ import type { SupportedLanguages } from '../../languages.js';
11
+ import type { ResolutionEvidence } from '../types.js';
12
+ import type { ShadowAgreement, ShadowDiff } from './diff.js';
13
+ export interface LanguageParityRow {
14
+ readonly language: SupportedLanguages;
15
+ readonly totalCalls: number;
16
+ readonly bothAgree: number;
17
+ readonly onlyLegacy: number;
18
+ readonly onlyNew: number;
19
+ readonly bothDisagree: number;
20
+ readonly bothEmpty: number;
21
+ /**
22
+ * Fraction in [0, 1]. Numerator = `bothAgree`; denominator = "calls where
23
+ * at least one side resolved" = `totalCalls - bothEmpty`.
24
+ *
25
+ * When the denominator is 0 (all calls for this language were
26
+ * `both-empty`), returns 0. Callers rendering the dashboard should treat
27
+ * a 0 parity alongside `totalCalls === bothEmpty` as "no signal" rather
28
+ * than "total disagreement".
29
+ */
30
+ readonly parity: number;
31
+ /**
32
+ * Divergence signals broken down by `ResolutionEvidence.kind`. Sourced
33
+ * from `ShadowDiff.evidenceDelta` on non-agreeing rows only — `both-agree`
34
+ * and `both-empty` do not contribute.
35
+ */
36
+ readonly evidenceBreakdown: ReadonlyMap<ResolutionEvidence['kind'], number>;
37
+ }
38
+ export interface ShadowParityReport {
39
+ readonly generatedAt: string;
40
+ readonly perLanguage: readonly LanguageParityRow[];
41
+ readonly overall: Omit<LanguageParityRow, 'language' | 'evidenceBreakdown'>;
42
+ }
43
+ /**
44
+ * Aggregate a stream of `ShadowDiff` records into a `ShadowParityReport`,
45
+ * bucketed by language. Pure function.
46
+ *
47
+ * - `perLanguage` rows are sorted alphabetically by `SupportedLanguages`
48
+ * value for stable JSON output (the dashboard reads
49
+ * `.gitnexus/shadow-parity/latest.json` and diffing snapshots is useful).
50
+ * - `overall` is the column-wise sum across languages.
51
+ * - `generatedAt` is injected via the `now` parameter so tests stay
52
+ * deterministic; production callers let it default to `new Date()`.
53
+ */
54
+ export declare function aggregateDiffs(diffs: readonly {
55
+ readonly language: SupportedLanguages;
56
+ readonly diff: ShadowDiff;
57
+ }[], now?: Date): ShadowParityReport;
58
+ export type { ShadowAgreement, ShadowDiff };
59
+ //# sourceMappingURL=aggregate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"aggregate.d.ts","sourceRoot":"","sources":["../../../src/scope-resolution/shadow/aggregate.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAC7D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACtD,OAAO,KAAK,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAI7D,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,QAAQ,EAAE,kBAAkB,CAAC;IACtC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B;;;;;;;;OAQG;IACH,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB;;;;OAIG;IACH,QAAQ,CAAC,iBAAiB,EAAE,WAAW,CAAC,kBAAkB,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,CAAC;CAC7E;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,WAAW,EAAE,SAAS,iBAAiB,EAAE,CAAC;IACnD,QAAQ,CAAC,OAAO,EAAE,IAAI,CAAC,iBAAiB,EAAE,UAAU,GAAG,mBAAmB,CAAC,CAAC;CAC7E;AAID;;;;;;;;;;GAUG;AACH,wBAAgB,cAAc,CAC5B,KAAK,EAAE,SAAS;IAAE,QAAQ,CAAC,QAAQ,EAAE,kBAAkB,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAA;CAAE,EAAE,EACtF,GAAG,GAAE,IAAiB,GACrB,kBAAkB,CAuBpB;AAiGD,YAAY,EAAE,eAAe,EAAE,UAAU,EAAE,CAAC"}
@@ -0,0 +1,117 @@
1
+ /**
2
+ * Shadow-mode aggregation — per-language parity %, per-evidence-kind
3
+ * breakdown of divergences. Consumed by the parity dashboard (RING2-PKG-5).
4
+ *
5
+ * Pure functions; no I/O. The harness persists per-run JSON; the dashboard
6
+ * reads `.gitnexus/shadow-parity/latest.json` and renders.
7
+ *
8
+ * Part of RFC #909 Ring 2 SHARED — #918.
9
+ */
10
+ // ─── Public API ─────────────────────────────────────────────────────────────
11
+ /**
12
+ * Aggregate a stream of `ShadowDiff` records into a `ShadowParityReport`,
13
+ * bucketed by language. Pure function.
14
+ *
15
+ * - `perLanguage` rows are sorted alphabetically by `SupportedLanguages`
16
+ * value for stable JSON output (the dashboard reads
17
+ * `.gitnexus/shadow-parity/latest.json` and diffing snapshots is useful).
18
+ * - `overall` is the column-wise sum across languages.
19
+ * - `generatedAt` is injected via the `now` parameter so tests stay
20
+ * deterministic; production callers let it default to `new Date()`.
21
+ */
22
+ export function aggregateDiffs(diffs, now = new Date()) {
23
+ const perLanguageMap = new Map();
24
+ for (const { language, diff } of diffs) {
25
+ let counts = perLanguageMap.get(language);
26
+ if (!counts) {
27
+ counts = makeEmptyCounts();
28
+ perLanguageMap.set(language, counts);
29
+ }
30
+ tallyDiff(counts, diff);
31
+ }
32
+ const perLanguage = Array.from(perLanguageMap.entries())
33
+ .map(([language, counts]) => buildRow(language, counts))
34
+ .sort((a, b) => a.language.localeCompare(b.language));
35
+ const overall = buildOverallRow(perLanguage);
36
+ return {
37
+ generatedAt: now.toISOString(),
38
+ perLanguage,
39
+ overall,
40
+ };
41
+ }
42
+ function makeEmptyCounts() {
43
+ return {
44
+ totalCalls: 0,
45
+ bothAgree: 0,
46
+ onlyLegacy: 0,
47
+ onlyNew: 0,
48
+ bothDisagree: 0,
49
+ bothEmpty: 0,
50
+ evidenceBreakdown: new Map(),
51
+ };
52
+ }
53
+ function tallyDiff(counts, diff) {
54
+ counts.totalCalls += 1;
55
+ incrementAgreement(counts, diff.agreement);
56
+ if (diff.agreement === 'both-agree' || diff.agreement === 'both-empty')
57
+ return;
58
+ for (const ev of diff.evidenceDelta) {
59
+ counts.evidenceBreakdown.set(ev.kind, (counts.evidenceBreakdown.get(ev.kind) ?? 0) + 1);
60
+ }
61
+ }
62
+ function incrementAgreement(counts, agreement) {
63
+ switch (agreement) {
64
+ case 'both-agree':
65
+ counts.bothAgree += 1;
66
+ return;
67
+ case 'only-legacy':
68
+ counts.onlyLegacy += 1;
69
+ return;
70
+ case 'only-new':
71
+ counts.onlyNew += 1;
72
+ return;
73
+ case 'both-disagree':
74
+ counts.bothDisagree += 1;
75
+ return;
76
+ case 'both-empty':
77
+ counts.bothEmpty += 1;
78
+ return;
79
+ }
80
+ }
81
+ function buildRow(language, counts) {
82
+ const resolved = counts.totalCalls - counts.bothEmpty;
83
+ const parity = resolved > 0 ? counts.bothAgree / resolved : 0;
84
+ return {
85
+ language,
86
+ totalCalls: counts.totalCalls,
87
+ bothAgree: counts.bothAgree,
88
+ onlyLegacy: counts.onlyLegacy,
89
+ onlyNew: counts.onlyNew,
90
+ bothDisagree: counts.bothDisagree,
91
+ bothEmpty: counts.bothEmpty,
92
+ parity,
93
+ // Freeze via `new Map` on a sorted-kind copy so downstream consumers
94
+ // can't mutate the aggregator's internal state.
95
+ evidenceBreakdown: new Map(Array.from(counts.evidenceBreakdown.entries()).sort(([a], [b]) => a.localeCompare(b))),
96
+ };
97
+ }
98
+ function buildOverallRow(perLanguage) {
99
+ let totalCalls = 0;
100
+ let bothAgree = 0;
101
+ let onlyLegacy = 0;
102
+ let onlyNew = 0;
103
+ let bothDisagree = 0;
104
+ let bothEmpty = 0;
105
+ for (const row of perLanguage) {
106
+ totalCalls += row.totalCalls;
107
+ bothAgree += row.bothAgree;
108
+ onlyLegacy += row.onlyLegacy;
109
+ onlyNew += row.onlyNew;
110
+ bothDisagree += row.bothDisagree;
111
+ bothEmpty += row.bothEmpty;
112
+ }
113
+ const resolved = totalCalls - bothEmpty;
114
+ const parity = resolved > 0 ? bothAgree / resolved : 0;
115
+ return { totalCalls, bothAgree, onlyLegacy, onlyNew, bothDisagree, bothEmpty, parity };
116
+ }
117
+ //# sourceMappingURL=aggregate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"aggregate.js","sourceRoot":"","sources":["../../../src/scope-resolution/shadow/aggregate.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Shadow-mode diff logic — RFC §6.3.
3
+ *
4
+ * Pure comparison logic for shadow mode. Takes two `Resolution[]` (legacy
5
+ * DAG result + new scope-based registry result) and produces a structured
6
+ * diff record for the parity dashboard.
7
+ *
8
+ * Consumed by the Ring 2 PKG shadow harness (#923), which dual-runs each
9
+ * call through legacy + new paths, diffs results, and persists per-run JSON
10
+ * for the parity dashboard.
11
+ *
12
+ * Part of RFC #909 Ring 2 SHARED — #918.
13
+ */
14
+ import type { Resolution, ResolutionEvidence } from '../types.js';
15
+ export type ShadowAgreement = 'both-agree' | 'only-legacy' | 'only-new' | 'both-disagree' | 'both-empty';
16
+ export interface ShadowDiff {
17
+ readonly callsite: ShadowCallsite;
18
+ readonly legacy: Resolution | null;
19
+ readonly newResult: Resolution | null;
20
+ readonly agreement: ShadowAgreement;
21
+ /**
22
+ * Symmetric difference of the two top resolutions' `evidence` arrays,
23
+ * keyed on `ResolutionEvidence.kind`.
24
+ *
25
+ * - For `'both-agree'` and `'both-empty'` agreements, always empty.
26
+ * - For `'both-disagree'`, contains evidence kinds present on exactly one
27
+ * side (not in both).
28
+ * - For `'only-legacy'`, contains all of legacy's top evidence.
29
+ * - For `'only-new'`, contains all of new's top evidence.
30
+ */
31
+ readonly evidenceDelta: readonly ResolutionEvidence[];
32
+ }
33
+ export interface ShadowCallsite {
34
+ readonly filePath: string;
35
+ readonly line: number;
36
+ readonly col: number;
37
+ readonly calledName: string;
38
+ }
39
+ /**
40
+ * Compare two `Resolution[]` arrays (top matches at `[0]`) and produce a
41
+ * `ShadowDiff`. Pure function.
42
+ *
43
+ * Agreement rules:
44
+ * - both arrays empty → `'both-empty'`, `evidenceDelta: []`
45
+ * - legacy empty, new non-empty → `'only-new'`, `evidenceDelta` = new's top evidence
46
+ * - legacy non-empty, new empty → `'only-legacy'`, `evidenceDelta` = legacy's top evidence
47
+ * - both non-empty, same top `def.nodeId` → `'both-agree'`, `evidenceDelta: []`
48
+ * - both non-empty, different top `def.nodeId` → `'both-disagree'`,
49
+ * `evidenceDelta` = symmetric difference by `ResolutionEvidence.kind`
50
+ * (first occurrence of a kind-only-on-legacy then kind-only-on-new; order
51
+ * preserved from input arrays)
52
+ *
53
+ * Evidence-delta rationale: callers aggregating divergences want to know
54
+ * which signal kinds explain a disagreement. Keying on `kind` (not full
55
+ * equality over `weight`/`note`) avoids spurious deltas when the same
56
+ * signal fires with slightly different calibration weights on each side.
57
+ */
58
+ export declare function diffResolutions(callsite: ShadowCallsite, legacy: readonly Resolution[], newResult: readonly Resolution[]): ShadowDiff;
59
+ //# sourceMappingURL=diff.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diff.d.ts","sourceRoot":"","sources":["../../../src/scope-resolution/shadow/diff.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAIlE,MAAM,MAAM,eAAe,GACvB,YAAY,GACZ,aAAa,GACb,UAAU,GACV,eAAe,GACf,YAAY,CAAC;AAEjB,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAC;IAClC,QAAQ,CAAC,MAAM,EAAE,UAAU,GAAG,IAAI,CAAC;IACnC,QAAQ,CAAC,SAAS,EAAE,UAAU,GAAG,IAAI,CAAC;IACtC,QAAQ,CAAC,SAAS,EAAE,eAAe,CAAC;IACpC;;;;;;;;;OASG;IACH,QAAQ,CAAC,aAAa,EAAE,SAAS,kBAAkB,EAAE,CAAC;CACvD;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B;AAID;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,cAAc,EACxB,MAAM,EAAE,SAAS,UAAU,EAAE,EAC7B,SAAS,EAAE,SAAS,UAAU,EAAE,GAC/B,UAAU,CAoBZ"}
@@ -0,0 +1,79 @@
1
+ /**
2
+ * Shadow-mode diff logic — RFC §6.3.
3
+ *
4
+ * Pure comparison logic for shadow mode. Takes two `Resolution[]` (legacy
5
+ * DAG result + new scope-based registry result) and produces a structured
6
+ * diff record for the parity dashboard.
7
+ *
8
+ * Consumed by the Ring 2 PKG shadow harness (#923), which dual-runs each
9
+ * call through legacy + new paths, diffs results, and persists per-run JSON
10
+ * for the parity dashboard.
11
+ *
12
+ * Part of RFC #909 Ring 2 SHARED — #918.
13
+ */
14
+ // ─── Public API ─────────────────────────────────────────────────────────────
15
+ /**
16
+ * Compare two `Resolution[]` arrays (top matches at `[0]`) and produce a
17
+ * `ShadowDiff`. Pure function.
18
+ *
19
+ * Agreement rules:
20
+ * - both arrays empty → `'both-empty'`, `evidenceDelta: []`
21
+ * - legacy empty, new non-empty → `'only-new'`, `evidenceDelta` = new's top evidence
22
+ * - legacy non-empty, new empty → `'only-legacy'`, `evidenceDelta` = legacy's top evidence
23
+ * - both non-empty, same top `def.nodeId` → `'both-agree'`, `evidenceDelta: []`
24
+ * - both non-empty, different top `def.nodeId` → `'both-disagree'`,
25
+ * `evidenceDelta` = symmetric difference by `ResolutionEvidence.kind`
26
+ * (first occurrence of a kind-only-on-legacy then kind-only-on-new; order
27
+ * preserved from input arrays)
28
+ *
29
+ * Evidence-delta rationale: callers aggregating divergences want to know
30
+ * which signal kinds explain a disagreement. Keying on `kind` (not full
31
+ * equality over `weight`/`note`) avoids spurious deltas when the same
32
+ * signal fires with slightly different calibration weights on each side.
33
+ */
34
+ export function diffResolutions(callsite, legacy, newResult) {
35
+ const legacyTop = legacy.length > 0 ? legacy[0] : null;
36
+ const newTop = newResult.length > 0 ? newResult[0] : null;
37
+ const agreement = (() => {
38
+ if (legacyTop === null && newTop === null)
39
+ return 'both-empty';
40
+ if (legacyTop === null)
41
+ return 'only-new';
42
+ if (newTop === null)
43
+ return 'only-legacy';
44
+ return legacyTop.def.nodeId === newTop.def.nodeId ? 'both-agree' : 'both-disagree';
45
+ })();
46
+ const evidenceDelta = computeEvidenceDelta(legacyTop, newTop, agreement);
47
+ return {
48
+ callsite,
49
+ legacy: legacyTop,
50
+ newResult: newTop,
51
+ agreement,
52
+ evidenceDelta,
53
+ };
54
+ }
55
+ // ─── Internal helpers ───────────────────────────────────────────────────────
56
+ /**
57
+ * Symmetric difference of two evidence arrays, keyed on
58
+ * `ResolutionEvidence.kind`. Preserves input order: legacy-only signals
59
+ * first (in legacy's original order), then new-only signals (in new's order).
60
+ *
61
+ * For `'both-agree'` / `'both-empty'` the delta is empty by contract. For
62
+ * `'only-legacy'` / `'only-new'` one side's evidence is the delta (nothing to
63
+ * subtract against).
64
+ */
65
+ function computeEvidenceDelta(legacy, newResult, agreement) {
66
+ if (agreement === 'both-agree' || agreement === 'both-empty')
67
+ return [];
68
+ if (agreement === 'only-legacy')
69
+ return legacy.evidence;
70
+ if (agreement === 'only-new')
71
+ return newResult.evidence;
72
+ // both-disagree: symmetric difference keyed on `kind`
73
+ const legacyKinds = new Set(legacy.evidence.map((e) => e.kind));
74
+ const newKinds = new Set(newResult.evidence.map((e) => e.kind));
75
+ const onlyInLegacy = legacy.evidence.filter((e) => !newKinds.has(e.kind));
76
+ const onlyInNew = newResult.evidence.filter((e) => !legacyKinds.has(e.kind));
77
+ return [...onlyInLegacy, ...onlyInNew];
78
+ }
79
+ //# sourceMappingURL=diff.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diff.js","sourceRoot":"","sources":["../../../src/scope-resolution/shadow/diff.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAsCH,+EAA+E;AAE/E;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,eAAe,CAC7B,QAAwB,EACxB,MAA6B,EAC7B,SAAgC;IAEhC,MAAM,SAAS,GAAsB,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAC1E,MAAM,MAAM,GAAsB,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAE7E,MAAM,SAAS,GAAoB,CAAC,GAAG,EAAE;QACvC,IAAI,SAAS,KAAK,IAAI,IAAI,MAAM,KAAK,IAAI;YAAE,OAAO,YAAY,CAAC;QAC/D,IAAI,SAAS,KAAK,IAAI;YAAE,OAAO,UAAU,CAAC;QAC1C,IAAI,MAAM,KAAK,IAAI;YAAE,OAAO,aAAa,CAAC;QAC1C,OAAO,SAAS,CAAC,GAAG,CAAC,MAAM,KAAK,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,eAAe,CAAC;IACrF,CAAC,CAAC,EAAE,CAAC;IAEL,MAAM,aAAa,GAAG,oBAAoB,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC;IAEzE,OAAO;QACL,QAAQ;QACR,MAAM,EAAE,SAAS;QACjB,SAAS,EAAE,MAAM;QACjB,SAAS;QACT,aAAa;KACd,CAAC;AACJ,CAAC;AAED,+EAA+E;AAE/E;;;;;;;;GAQG;AACH,SAAS,oBAAoB,CAC3B,MAAyB,EACzB,SAA4B,EAC5B,SAA0B;IAE1B,IAAI,SAAS,KAAK,YAAY,IAAI,SAAS,KAAK,YAAY;QAAE,OAAO,EAAE,CAAC;IACxE,IAAI,SAAS,KAAK,aAAa;QAAE,OAAO,MAAO,CAAC,QAAQ,CAAC;IACzD,IAAI,SAAS,KAAK,UAAU;QAAE,OAAO,SAAU,CAAC,QAAQ,CAAC;IAEzD,sDAAsD;IACtD,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,MAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IACjE,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,SAAU,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IAEjE,MAAM,YAAY,GAAG,MAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IAC3E,MAAM,SAAS,GAAG,SAAU,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IAE9E,OAAO,CAAC,GAAG,YAAY,EAAE,GAAG,SAAS,CAAC,CAAC;AACzC,CAAC"}
@@ -42,6 +42,142 @@ export interface Capture {
42
42
  /** The captured source text. */
43
43
  readonly text: string;
44
44
  }
45
+ /**
46
+ * A grouping of `Capture`s that came from a single query match (e.g., one
47
+ * `@import.statement` match carries `@import.source`, `@import.name`,
48
+ * `@import.alias?` as child captures). Keyed by capture name for O(1)
49
+ * child access.
50
+ */
51
+ export type CaptureMatch = Readonly<Record<string, Capture>>;
52
+ /**
53
+ * Provider-interpreted raw import, consumed by finalize (Phase 2) to produce
54
+ * linked `ImportEdge[]`. The provider's `interpretImport` hook turns a
55
+ * `CaptureMatch` for an `@import.statement` into one of these; the central
56
+ * finalize algorithm resolves `targetRaw` to a concrete file via
57
+ * `resolveImportTarget` and materializes the final `ImportEdge`.
58
+ *
59
+ * Discriminated union — each variant carries only the fields that make sense
60
+ * for its kind. Invalid shapes (e.g., a `namespace` import with an alias-like
61
+ * `importedName` mismatch) are compile errors, not latent bugs. `'wildcard-
62
+ * expanded'` is deliberately NOT a variant: that kind is finalize output only,
63
+ * produced when `expandsWildcardTo` materializes a wildcard against target
64
+ * exports — a provider must never emit it at parse time.
65
+ */
66
+ export type ParsedImport =
67
+ /**
68
+ * Per-name import without rename.
69
+ *
70
+ * Examples:
71
+ * - Python `from foo import X` → `{ kind: 'named', localName: 'X', importedName: 'X', targetRaw: 'foo' }`
72
+ * - TS `import { X } from './foo'` → `{ kind: 'named', localName: 'X', importedName: 'X', targetRaw: './foo' }`
73
+ * - Java `import foo.bar.X` → `{ kind: 'named', localName: 'X', importedName: 'X', targetRaw: 'foo.bar' }`
74
+ */
75
+ {
76
+ readonly kind: 'named';
77
+ readonly localName: string;
78
+ readonly importedName: string;
79
+ readonly targetRaw: string;
80
+ }
81
+ /**
82
+ * Per-name import with rename.
83
+ *
84
+ * Examples:
85
+ * - Python `from foo import X as Y` → `{ kind: 'alias', localName: 'Y', importedName: 'X', alias: 'Y', targetRaw: 'foo' }`
86
+ * - TS `import { X as Y } from './foo'` → `{ kind: 'alias', localName: 'Y', importedName: 'X', alias: 'Y', targetRaw: './foo' }`
87
+ */
88
+ | {
89
+ readonly kind: 'alias';
90
+ readonly localName: string;
91
+ readonly importedName: string;
92
+ readonly alias: string;
93
+ readonly targetRaw: string;
94
+ }
95
+ /**
96
+ * Qualified module handle, with or without rename. `importedName` is the
97
+ * module being aliased; `localName` is the scope-visible handle (often the
98
+ * same unless renamed).
99
+ *
100
+ * Examples:
101
+ * - Python `import numpy` → `{ kind: 'namespace', localName: 'numpy', importedName: 'numpy', targetRaw: 'numpy' }`
102
+ * - Python `import numpy as np` → `{ kind: 'namespace', localName: 'np', importedName: 'numpy', targetRaw: 'numpy' }`
103
+ * - TS `import * as np from 'numpy'` → `{ kind: 'namespace', localName: 'np', importedName: 'numpy', targetRaw: 'numpy' }`
104
+ * - Go `import foo "pkg/bar"` → `{ kind: 'namespace', localName: 'foo', importedName: 'bar', targetRaw: 'pkg/bar' }`
105
+ */
106
+ | {
107
+ readonly kind: 'namespace';
108
+ /** Scope-visible handle (e.g. `np` in `import numpy as np`; `numpy` when unaliased). */
109
+ readonly localName: string;
110
+ /** Module being aliased (e.g. `numpy` in `import numpy as np`). */
111
+ readonly importedName: string;
112
+ readonly targetRaw: string;
113
+ }
114
+ /**
115
+ * Syntactically-detectable parse-time re-export. Finalize may still produce
116
+ * `ImportEdge { kind: 'reexport', transitiveVia }` when flattening chains;
117
+ * this variant preserves the *parse-time* signal so finalize doesn't have
118
+ * to re-derive it from scratch.
119
+ *
120
+ * Examples:
121
+ * - TS `export { X } from './y'` → `{ kind: 'reexport', localName: 'X', importedName: 'X', targetRaw: './y' }`
122
+ * - TS `export { X as Y } from './y'` → `{ kind: 'reexport', localName: 'Y', importedName: 'X', alias: 'Y', targetRaw: './y' }`
123
+ * - Rust `pub use foo::bar` → `{ kind: 'reexport', localName: 'bar', importedName: 'bar', targetRaw: 'foo' }`
124
+ */
125
+ | {
126
+ readonly kind: 'reexport';
127
+ /** Name as re-exported in the current module. */
128
+ readonly localName: string;
129
+ /** Name in the source module. */
130
+ readonly importedName: string;
131
+ readonly targetRaw: string;
132
+ /** Set when the re-export renames the symbol (e.g. `export { X as Y } from './y'`). */
133
+ readonly alias?: string;
134
+ }
135
+ /**
136
+ * Runtime-computed target — the import path is not a static literal at
137
+ * parse time. Providers SHOULD emit the unresolvable expression's source
138
+ * text as `targetRaw` to aid diagnostics; `null` only when no string form
139
+ * exists.
140
+ *
141
+ * Examples:
142
+ * - JS `await import(expr)` → `{ kind: 'dynamic-unresolved', localName: '', targetRaw: 'expr' }`
143
+ * - Python `importlib.import_module(f'pkg.{name}')` → `{ kind: 'dynamic-unresolved', localName: '', targetRaw: "f'pkg.{name}'" }`
144
+ */
145
+ | {
146
+ readonly kind: 'dynamic-unresolved';
147
+ readonly localName: string;
148
+ /** Source text of the unresolved expression when available; `null` otherwise. */
149
+ readonly targetRaw: string | null;
150
+ };
151
+ /**
152
+ * Provider-interpreted type binding. The provider's `interpretTypeBinding`
153
+ * hook turns a `CaptureMatch` (e.g., `@type-binding.parameter`) into one of
154
+ * these; the central extractor attaches the resulting `TypeRef` to the
155
+ * appropriate scope's `typeBindings` map.
156
+ */
157
+ export interface ParsedTypeBinding {
158
+ /** The name being bound (parameter name, `self`, assignment LHS, …). */
159
+ readonly boundName: string;
160
+ /** The raw type name as written in source (`'User'`, `'models.User'`, …). */
161
+ readonly rawTypeName: string;
162
+ readonly source: TypeRef['source'];
163
+ }
164
+ /**
165
+ * Cross-file workspace index consumed by finalize-phase hooks
166
+ * (`resolveImportTarget`, `expandsWildcardTo`). Opaque placeholder in Ring 1;
167
+ * concretely typed in Ring 2 SHARED (#915).
168
+ */
169
+ export type WorkspaceIndex = unknown;
170
+ /**
171
+ * Scope tree handle consumed by parse-phase hooks (`bindingScopeFor`,
172
+ * `importOwningScope`) to navigate the in-progress scope tree. Opaque
173
+ * placeholder in Ring 1; concretely typed in Ring 2 SHARED (#912).
174
+ */
175
+ export type ScopeTree = unknown;
176
+ /** Call-site description passed to `arityCompatibility`. */
177
+ export interface Callsite {
178
+ /** Number of arguments at the call site. */
179
+ readonly arity: number;
180
+ }
45
181
  /**
46
182
  * A cross-file import edge attached to a module/namespace scope.
47
183
  *
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/scope-resolution/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/scope-resolution/types.ts"],"names":[],"mappings":"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"}
@@ -8,7 +8,7 @@
8
8
  * The providers table in `languages/index.ts` uses `satisfies Record<SupportedLanguages, LanguageProvider>`
9
9
  * so adding a language to the enum without creating a provider is a compiler error.
10
10
  */
11
- import type { SupportedLanguages, MroStrategy } from '../../_shared/index.js';
11
+ import type { SupportedLanguages, MroStrategy, Capture, CaptureMatch, BindingRef, TypeRef, Scope, ScopeId, ScopeKind, ScopeTree, ParsedImport, ParsedTypeBinding, SymbolDefinition, Callsite, WorkspaceIndex } from '../../_shared/index.js';
12
12
  import type { LanguageTypeConfig } from './type-extractors/types.js';
13
13
  import type { CallRouter } from './call-routing.js';
14
14
  import type { CallExtractor, DispatchDecision, ImplicitReceiverOverride, ReceiverEnriched } from './call-types.js';
@@ -222,6 +222,177 @@ interface LanguageProviderConfig {
222
222
  /** Built-in/stdlib names that should be filtered from the call graph for this language.
223
223
  * Default: undefined (no language-specific filtering). */
224
224
  readonly builtInNames?: ReadonlySet<string>;
225
+ /**
226
+ * Emit scope captures from raw source. Tree-sitter-based providers run a
227
+ * `scopes.scm` query; standalone providers (COBOL) emit captures from a
228
+ * regex tagger. The return shape is parser-agnostic: the central
229
+ * `ScopeExtractor` consumes `Capture[]` without knowing which parser
230
+ * produced them.
231
+ *
232
+ * Required for any provider participating in scope-based resolution.
233
+ * Providers that have not yet migrated continue to run through the legacy
234
+ * DAG path (feature-flagged per `REGISTRY_PRIMARY_<LANG>`).
235
+ *
236
+ * Default: undefined (language continues to use legacy DAG).
237
+ */
238
+ readonly emitScopeCaptures?: (sourceText: string, filePath: string) => Promise<readonly Capture[]>;
239
+ /**
240
+ * Interpret a raw `@import.statement` capture group into a `ParsedImport`.
241
+ * The central finalize algorithm resolves `ParsedImport.targetRaw` to a
242
+ * concrete file via `resolveImportTarget` and materializes the final
243
+ * `ImportEdge` with `targetModuleScope` / `targetDefId` filled in.
244
+ *
245
+ * Required when `emitScopeCaptures` is implemented.
246
+ */
247
+ readonly interpretImport?: (captures: CaptureMatch) => ParsedImport | null;
248
+ /**
249
+ * What is the implicit receiver on a Function scope? For instance methods
250
+ * this is `self`/`this`; for standalone functions it is `null`. Consulted
251
+ * by `Registry.lookup` Step 2 via the `resolveTypeRef` helper.
252
+ *
253
+ * Required for any language with method dispatch (OO semantics).
254
+ *
255
+ * Default: undefined (treated as `null` — no implicit receiver).
256
+ */
257
+ readonly receiverBinding?: (functionScope: Scope) => TypeRef | null;
258
+ /**
259
+ * Interpret a raw type-binding capture (parameter annotation, `self`,
260
+ * assignment with constructor RHS, …) into a `ParsedTypeBinding`. The
261
+ * central extractor attaches the resulting `TypeRef` to the appropriate
262
+ * scope's `typeBindings` map.
263
+ *
264
+ * Default: undefined (falls back to `{ boundName: captures.name, rawTypeName: captures.type, source: 'annotation' }`).
265
+ */
266
+ readonly interpretTypeBinding?: (captures: CaptureMatch) => ParsedTypeBinding | null;
267
+ /**
268
+ * Override the `ScopeKind` assigned to a scope capture. Use when the
269
+ * capture name alone can't resolve the kind (e.g., tree-sitter captures
270
+ * a `block` that is semantically an `Expression` in this language).
271
+ *
272
+ * Default: undefined (the central extractor uses the capture name's
273
+ * suffix — `@scope.function` → `'Function'`, etc.).
274
+ */
275
+ readonly resolveScopeKind?: (captures: CaptureMatch) => ScopeKind | null;
276
+ /**
277
+ * Should this scope capture materialize as a real `Scope` node? Return
278
+ * `false` to skip scope creation while still emitting declarations that
279
+ * would have gone inside (they attach to the enclosing real scope).
280
+ *
281
+ * Example: Python `if`/`for`/`while` bodies capture as `@scope.block` but
282
+ * Python has no block scope — hook returns `false` and child declarations
283
+ * lift to the enclosing function/module.
284
+ *
285
+ * Default: undefined (treated as `true` — always create).
286
+ */
287
+ readonly shouldCreateScope?: (captures: CaptureMatch) => boolean;
288
+ /**
289
+ * Override where a declaration's name becomes visible. By default the name
290
+ * is bound in the innermost enclosing scope; return a different `ScopeId`
291
+ * to hoist it (JS `var` → enclosing function scope; Ruby `def` inside
292
+ * `begin` → enclosing class scope).
293
+ *
294
+ * Return `null` to delegate to the central default (innermost enclosing
295
+ * scope). This matches the `X | null` convention used by the other optional
296
+ * hooks and supports partial overrides — e.g., a JS provider can return a
297
+ * hoisted scope for `var` declarations and `null` for `let`/`const`, without
298
+ * re-implementing the default lookup.
299
+ *
300
+ * **Purity:** must be a pure function of its inputs — same parameters must
301
+ * yield the same `ScopeId` (or `null`) across invocations. No closure over
302
+ * mutable state. Required so scope-tree construction stays deterministic
303
+ * across re-parses.
304
+ *
305
+ * Default: undefined (the central extractor uses `innermostScope.id`).
306
+ */
307
+ readonly bindingScopeFor?: (declCapture: CaptureMatch, innermostScope: Scope, scopeTree: ScopeTree) => ScopeId | null;
308
+ /**
309
+ * Resolve a `ParsedImport.targetRaw` expression to a concrete file path in
310
+ * the workspace. Language-specific resolution: Python relative imports,
311
+ * JS package.json + node_modules, Go module paths, Java classpath,
312
+ * COBOL COPY paths. Ports today's per-language import resolver.
313
+ *
314
+ * Required when `emitScopeCaptures` is implemented. Ring 2 PKG #922
315
+ * provides the adapter that bridges today's resolver shape to this hook.
316
+ */
317
+ readonly resolveImportTarget?: (parsedImport: ParsedImport, workspaceIndex: WorkspaceIndex) => string | null;
318
+ /**
319
+ * Enumerate the exported names of a file — used by the finalize algorithm
320
+ * to expand `import * from M` into individual `BindingRef`s with
321
+ * `origin: 'wildcard'`.
322
+ *
323
+ * Default: undefined (central finalize walks the target file's
324
+ * `ExportMap.keys()`).
325
+ */
326
+ readonly expandsWildcardTo?: (targetFile: string, workspaceIndex: WorkspaceIndex) => readonly string[];
327
+ /**
328
+ * Decide the scope to which a `ParsedImport` attaches. Most languages
329
+ * attach imports to the nearest enclosing `Module`/`Namespace` scope
330
+ * (the default); some languages allow local imports (Python function-local
331
+ * `from x import Y`, Rust fn-local `use`, TS dynamic `import()`) — return
332
+ * a `Function`/`Block` scope id instead.
333
+ *
334
+ * Return `null` to delegate to the central default (nearest enclosing
335
+ * `Module`/`Namespace`). This matches the `X | null` convention used by
336
+ * the other optional hooks and supports partial overrides — a provider
337
+ * that handles only specific import forms non-standardly can `return null`
338
+ * for the common cases and let the central walk handle them.
339
+ *
340
+ * **Purity:** must be a pure function of its inputs — same parameters must
341
+ * yield the same `ScopeId` (or `null`) across invocations. No closure over
342
+ * mutable state. Required so scope-tree construction stays deterministic
343
+ * across re-parses.
344
+ *
345
+ * Default: undefined (central finalize walks to the nearest enclosing
346
+ * `Module` or `Namespace` scope).
347
+ */
348
+ readonly importOwningScope?: (parsedImport: ParsedImport, innermostScope: Scope, scopeTree: ScopeTree) => ScopeId | null;
349
+ /**
350
+ * Merge local declarations and imported bindings for a single (scope, name)
351
+ * during finalize materialization of a scope's binding table. Language-
352
+ * specific precedence: Python local hides import; TypeScript namespace
353
+ * merging keeps both; Ruby constant resolution has its own rules.
354
+ *
355
+ * Default: undefined (central finalize uses local-first-then-imports,
356
+ * deduping by `DefId`).
357
+ */
358
+ readonly mergeBindings?: (scope: Scope, bindings: readonly BindingRef[]) => readonly BindingRef[];
359
+ /**
360
+ * Classify a `@reference.call` capture as free / member / constructor /
361
+ * index. Preferred path is declarative via capture sub-tags
362
+ * (`@reference.call.free`, etc.); this hook handles the languages where
363
+ * call form can't be decided statically (Ruby bare `foo(x)` is free-or-
364
+ * member until resolved).
365
+ *
366
+ * Default: undefined (central extractor reads capture sub-tag if present;
367
+ * else treats as `'free'`).
368
+ */
369
+ readonly classifyCallForm?: (captures: CaptureMatch, enclosingScope: Scope) => 'free' | 'member' | 'constructor' | 'index';
370
+ /**
371
+ * Does a binding at this scope shadow bindings of the same name in outer
372
+ * scopes? Default: any binding shadows (standard lexical scoping). Return
373
+ * `false` for transparent-scope edge cases (Python `from x import *`
374
+ * contexts, JS `var` hoisting quirks, COBOL PARAGRAPH transparency).
375
+ *
376
+ * Consulted by `Registry.lookup` Step 1 and by `resolveTypeRef` for
377
+ * shadowing decisions during the lexical chain walk.
378
+ *
379
+ * Default: undefined (treated as `true` — any binding shadows).
380
+ */
381
+ readonly shouldShadow?: (scope: Scope, bindings: readonly BindingRef[]) => boolean;
382
+ /**
383
+ * Is this callable definition compatible with the given call-site arity?
384
+ * Language-specific rules: Python `*args`/`**kwargs`/defaults, JS default
385
+ * params + rest, Kotlin vararg + defaults, Ruby optional/splat/block, Go
386
+ * straight counts, Rust no-variadic-no-defaults.
387
+ *
388
+ * `'incompatible'` is a soft penalty (−0.15 per EvidenceWeights) and is
389
+ * filtered only when at least one `'compatible'` candidate exists;
390
+ * otherwise the incompatible candidate is kept with the penalty so the
391
+ * call-site still links to a best-guess target.
392
+ *
393
+ * Default: undefined (treated as `'unknown'` — no signal either way).
394
+ */
395
+ readonly arityCompatibility?: (def: SymbolDefinition, callsite: Callsite) => 'compatible' | 'unknown' | 'incompatible';
225
396
  }
226
397
  /** Runtime type — same as LanguageProviderConfig but with defaults guaranteed present. */
227
398
  export interface LanguageProvider extends Omit<LanguageProviderConfig, 'importSemantics' | 'heritageDefaultEdge' | 'mroStrategy'> {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gitnexus",
3
- "version": "1.6.3-rc.2",
3
+ "version": "1.6.3-rc.4",
4
4
  "description": "Graph-powered code intelligence for AI agents. Index any codebase, query via MCP or CLI.",
5
5
  "author": "Abhigyan Patwari",
6
6
  "license": "PolyForm-Noncommercial-1.0.0",