feat(types): hybrid type resolution — closes #13#29
Merged
Conversation
Phase 1 Step 3 (final Phase 1 issue): import-aware CALLS edge refinement. Worker (full-stack-developer) implemented core feature + tests before session timeout. BOS completed docs + 1-line regression fix + commit/PR. Core feature (worker): - scripts/hybrid_type_resolver.py (1383 lines): build_import_registry, resolve_receiver_type, refine_call_edges. Parses Python from/import + TS/JS import statements, stores in import_registry SQLite table, writes IMPORTS edges to graph_edges, refines CALLS edges with resolved target_id + extra_json metadata. - scripts/commands/resolve_types.py: new CLI command (auto-registered). - scripts/commands/scan.py: calls refine_call_edges after graph population. Scan output adds type_resolution field. - scripts/graph_model.py: graph_stats reports IMPORTS edges. - tests/test_hybrid_type_resolver.py: 25 tests, all pass. Includes synthetic fixture (tests/fixtures/type_resolution/) with Cache.update vs Profile.update disambiguation case. - tests/test_graph_model.py + test_compact_format.py: updated assertions to account for IMPORTS edges now present in graph. BOS fixes: - scripts/mcp_server.py: removed manual format field from architecture tool definition (was preventing _inject_format_enum from adding compact enum, causing test_all_tools_have_format_enum regression). - README.md: added resolve-types to Architecture command table. - SKILL-QUICK.md: added resolve-types to Architecture section (9->10), updated total commands 58->60 (added resolve-types + git-status), updated MCP tools 56->58 (51 static + 7 dynamic, added codelens_resolve_types + codelens_git_status). - CHANGELOG.md: added Hybrid Type Resolution (issue #13) section under [8.2.0] with full API docs + refinement stats. Verified: - 25/25 new tests pass (test_hybrid_type_resolver.py) - Full suite: 4 pre-existing failures only (test_hybrid_engine.py confidence fields, present on main before any Phase 1 work) - Functional: scan on clean_app = type_resolution {edges_refined: 11, edges_unresolved: 55}. resolve-types standalone returns same stats. - IMPORTS edges: 37 in graph_edges (from 37 import statements). - import_registry table: 37 rows. - Synthetic fixture: user.profile.update() correctly refines to Profile.update even with Cache.update competitor. Co-authored-by: worker-3 <worker@codeassistant.local>
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
|
This was referenced Jun 28, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.


Summary
Phase 1 Step 3 (final Phase 1 issue): import-aware CALLS edge refinement.
Adds a post-AST-pass type resolution layer (
scripts/hybrid_type_resolver.py) that uses a per-file import registry to refine CALLS edges. Previouslyuser.profile.update()was recorded as a call toupdatewith no target type. Now the receiver type is resolved via the import registry, and the CALLS edge'starget_idis refined to the correct target node.Files
Created (5):
scripts/hybrid_type_resolver.py(1383 lines) — import registry builder, receiver type resolver, CALLS edge refinerscripts/commands/resolve_types.py(94 lines) — new CLI command (auto-registered)tests/test_hybrid_type_resolver.py(601 lines) — 25 teststests/fixtures/type_resolution/{main,models,cache}.py— synthetic fixture for disambiguation testingModified (7):
scripts/commands/scan.py— callsrefine_call_edgesafter graph population; addstype_resolutionfield to outputscripts/graph_model.py—graph_stats()reports IMPORTS edgesscripts/mcp_server.py— removed manualformatfield from architecture tool (was blocking compact enum injection, caused test regression)tests/test_graph_model.py— updated assertions for IMPORTS edgestests/test_compact_format.py— updated assertions for IMPORTS edgesREADME.md— addedresolve-typesto Architecture command tableSKILL-QUICK.md— addedresolve-types, updated total commands 58→60, MCP tools 56→58CHANGELOG.md— added Hybrid Type Resolution (issue [FEATURE] Hybrid type resolution: import-aware call edge refinement #13) section under [8.2.0]Test Results
test_compact_format.py::TestMCPGraphSchemaTool::test_all_tools_have_format_enumregression fixed by removing manualformatfield from architecture tool definition.Functional Verification (by BOS, independent)
scanon clean_app:type_resolution: {edges_refined: 11, edges_unresolved: 55}resolve-typesstandalone: returns same stats +import_registry_size: 37import_registrytable: 37 rowstests/fixtures/type_resolution/):user.profile.update()correctly refines toProfile.updateeven whenCache.updatecompetitor exists (without type resolution, edge_resolver picks Cache.update alphabetically)Non-Breaking
resolution_attemptedflag. No CALLS edge ever deleted.import_registrytable is additive — no existing table modified.Closes #13
Phase 1 (#21) checklist status after this PR:
get_architecture— single-call codebase overview for agents #19 — get_architectureFollow-up #25 still open: incremental scan does not populate graph tables.