* Initial plan
* Initial setup - Phase 9 BindingAccumulator cross-file return type wiring
Agent-Logs-Url: https://github.com/abhigyanpatwari/GitNexus/sessions/7cee6490-090d-4714-8cb5-a704168ff47a
* feat(SM-15): wire BindingAccumulator into processCallsFromExtracted for Phase 9 cross-file return type propagation
Agent-Logs-Url: https://github.com/abhigyanpatwari/GitNexus/sessions/7cee6490-090d-4714-8cb5-a704168ff47a
* fix(SM-15): address all PR #763 review findings
Performance (R1)
- Changed _fileScopeByFile from Map<string, [string,string][]> to
Map<string, Map<string,string>>. fileScopeGet(filePath, name) is
now O(1) — replaces the O(n) linear scan + defensive-copy alloc
that ran once per ConstructorBinding entry. fileScopeEntries()
reconstructs tuples from Map.entries() for backward compat.
- Updated finalize() dev-mode invariant to compare deduplicated Map
size rather than raw array length (Map.set deduplicates same-name).
Lifecycle (R2)
- Documented that Phase 9 intentionally reads pre-finalize because
finalize() cannot move before both the worker consumer (line 984)
AND the sequential-path writer (line 1061). Pre-finalize reads are
safe because finalize() is write-lock-only with no side effects.
Replaced the ambiguous "populated but not yet finalized" comment
with the full lifecycle ordering explanation.
Sequential-path parity (R3)
- Wired bindingAccumulator into processCalls at line 797 (sequential
path) so verifyConstructorBindings gets the Phase 9 fallback.
- Added bindingAccumulator parameter to processAssignmentsFromExtracted
signature and wired it at the pipeline.ts call site (line 1026).
- Both paths now produce identical Phase 9 behavior for the same code.
Tracking comments (R4)
- Added "Overlapping mechanism (N of 3)" cross-references at:
1. buildImportedReturnTypes (~line 109)
2. collectExportedBindings (~line 168)
3. Phase 9 fallback in verifyConstructorBindings (~line 563)
Each links to the other two and notes future unification.
Language coverage (R5)
- Added 5 new Phase 9 integration test suites in cross-file-binding.test.ts:
JavaScript, C++, C#, PHP, Ruby. Each uses the existing fixture
directories and asserts getUser() → User → user.save() resolves.
Total cross-file binding tests: 52 (was 37).
Quality asymmetry (R6)
- Added inline comment at the Phase 9 fallback noting worker-path
entries are Tier 0/1 only and that binding accuracy is structurally
lower for large repos where the worker path dominates.
Tests (+21 new)
- 6 fileScopeGet unit tests (happy path, unknown file/name, mixed
scopes, post-dispose, duplicate varName last-write-wins)
- 15 integration tests across 5 new language suites
Verification
- tsc --noEmit clean
- 3147 unit tests pass (+6 new)
- 52 cross-file binding integration tests pass (+15 new)
- 1766 resolver integration tests pass
- Zero regressions
Plan: docs/plans/2026-04-10-001-fix-sm15-review-findings-plan.md
Review: https://github.com/abhigyanpatwari/GitNexus/pull/763#issuecomment-4220354242
* fix(SM-15): gate accumulator fallback on resolution tier and fix sequential file-order dependency
Two Codex adversarial reviews identified medium-severity bugs in the Phase 9
BindingAccumulator fallback:
1. Local-first violation: the fallback fired regardless of whether ctx.resolve()
found same-file candidates, letting an imported callee shadow a local one
and produce false CALLS edges. Fixed by gating on tiered.tier !== 'same-file'
and callableDefs.length <= 1.
2. Sequential file-order dependency: processCalls flushed and verified per-file,
so consumer files processed before their providers missed accumulator bindings.
Fixed by splitting into a flush pre-pass (all files) then a resolution loop,
mirroring the worker path's "all appends before any reads" pattern.
Also adds 11 consumer-before-provider integration test fixtures (one per
supported language) and 4 unit tests for tier gating edge cases.
* refactor(SM-15): eliminate duplicated prepare logic in processCalls two-pass split
Replace the duplicated pre-pass + legacy-path code (parse → query → heritage
→ TypeEnv → exports) with a single preparation loop followed by a resolution
loop. Both paths now share the same preparation code — the only conditional
is the accumulator flush.
Side benefit: globalParentMap is now fully populated before any resolution
runs, improving cross-file isSubclassOf accuracy regardless of file order.
Net -118 lines (226 removed, 108 added).
* fix(SM-15): address PR #763 third-pass review findings
1. Update stale dispose() JSDoc — remove forward-reference to Phase 9
wiring that is now complete; document actual consumers.
2. Add processAssignmentsFromExtracted Phase 9 unit test — verifies the
accumulator fallback produces ACCESSES write edges when the SymbolTable
has no returnType for the callee.
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: Gergo Magyar <gergomagyar@icloud.com>