60%

§02 call resolution tier1 heuristic

Goal

Increase grounded ADR-high CALLS and remove suspect false binds through qualified-path and import-scope resolution. Retain raw and eligible-recall regressions in the durable stop record and preserve receiver-blind method guards.

Implementation Sketch

  • _resolve_target_py: normalize scoped_identifier text (strip super::/crate::/self::, resolve use-aliases from IMPORTS records) before by_qn; then import-narrowed by_name (candidate must be import-reachable from source file’s crate); provenance tags mark the tier.
  • _STD_METHOD_DENYLIST and the method-shape arity bypass stay — false binds are worse than dangling (deep-read finding).
  • Measurement: resolved/dangling counted live pre/post each improvement; stop when marginal gain < the recorded threshold (deepseek F2); readings land in the section record.

Spec References

  • intel_repo/neo4j/import_code_graph.py:_resolve_target_py + _build_symbol_index; intel_repo/neo4j/extract_symbols.py (call_shape derivation); .claude/rules/intelligence.md (graph-first surface this feeds)

Work Items

  • TDD matrix before resolver changes: add failing extraction and resolution pins for source-relative paths, simple and grouped aliases, import-reachable homonyms, ambiguous globs, external/std targets, bulk/incremental parity, and receiver-shaped negatives; retain every existing path-tail, arity, macro, and method-guard pin
  • Import-scope evidence and index: extend Rust import extraction to preserve each imported leaf, its local alias, grouped/glob semantics, and source file; build one canonical source-file import-scope index consumed by both bulk and incremental resolution, with missing or ambiguous reachability remaining unresolved
  • Qualified-path resolution: treat the existing final-segment path fallback as baseline behavior; resolve source-relative crate::/super::/self:: paths and imported or aliased prefixes through the canonical source-file import-scope index into by_qn before that fallback, while leaving external, ambiguous, and receiver-blind method targets unresolved
  • Resolution evidence contract: return and persist the accepted ADR 01 match_tier for every resolved tree-sitter CALLS edge through the shared bulk/incremental merge path, extend the central edge-confidence mapping only for genuinely new import-evidence tiers, and verify no parallel provenance or confidence encoding is introduced
  • Recall and precision measurement harness: capture a fresh fitness and scoped-call baseline, fully refresh the graph after each improvement, record resolved/dangling deltas by match tier and eligible project-local path class, require the false-bind negative corpus to remain green, and apply the recorded marginal-gain stop rule only to precision-preserving gains
  • Graph lifecycle closeout: after the final full refresh, remove only UnresolvedSymbol nodes with no inbound registered unresolved relationship, run graph-contract verification, update the resolved-CALLS fitness observation and per-tier readings in the section record, and confirm the section-owned fitness criterion

Evidence

  • Durable acceptance SSOT: content/evidence/call-resolution-tier1-acceptance.json.
  • Generate the artifact with measure-call-resolution.py compare --acceptance-output from the gitignored comparable before/after reports.
  • Validate source-report SHA-256 hashes, graph/corpus heads, equal denominators, required tiers/classes, finite readings, precision, regressions, and the applied stop verdict.
  • Precision gate: intel_repo/tests/prove_call_resolution_tier1.py --negative-only passed 54 false-bind negative cases.
  • Acceptance verdict: retain increased ADR-high resolution and reduced suspect resolution under the green precision gate.
  • Stop verdict: retain raw resolved and eligible-recall regressions; do not report a raw-recall improvement.
  • Cleanup registry edge set: CALLS, IMPLEMENTS, IMPORTS, USES.
  • Cleanup dry-run: before 0, removed 0, after 0.
  • Cleanup apply: before 0, removed 0, after 0.
  • Post-apply dry-run: before 0, removed 0, after 0.
  • Graph contract: status=ok, mismatches=[].

Criterion State

  • sc-039dfcef: probe-sourced true from the bounded durable-evidence verifier.
  • Treat the durable acceptance artifact as the historical Tier-1 completion record; do not query Neo4j to reconstruct it.
  • Require Tier-2 SCIP work to exceed the authoritative Tier-1 resolved-CALLS edge-ratio floor while preserving the plan-level 0.90 target.

Fresh intel (regenerated)

The section serves the mission, but its implementation shape must be regrounded before execution. The live graph has 33,962 resolved Ori CALLS and 76,421 unresolved CALLS edges, for a fitness ratio of 0.307674. Scoped unresolved calls are a large, concrete opportunity: 18,157 edges have ::, including 17,952 type-or-module paths. However, the current _resolve_target_py already has a final-segment path fallback, so a work item phrased as adding that fallback would duplicate shipped behavior without solving the dominant ambiguity.

Three decisions are forced:

  1. Treat the existing final-segment fallback as baseline behavior, not the deliverable. The new tier must resolve source-relative crate::/super::/self:: paths and imported/aliased prefixes against canonical qualified names before any bare-name fallback.
  2. Build one source-file import-scope model with complete Rust use-tree and alias evidence. Current imports.scm captures only selected path nodes and does not persist alias names; current IMPORTS relationships therefore cannot support the section’s alias claim as written.
  3. Return resolution evidence with every resolved CALLS edge. The accepted ADR requires provenance + match_tier, but every live Ori CALLS edge currently has match_tier = null; the section must use the ADR’s existing tiers rather than add heuristic-import-narrowed as a parallel provenance policy.

[JOIN] The live Pool::new cluster proves the required shape. It has 1,057 unresolved occurrences; a file such as compiler/ori_repr/src/tests.rs imports ori_types::Pool, while bare new has many graph candidates. Final-segment fallback cannot resolve this safely, but source-file import evidence can map Pool::new to the imported type path before qualified-name lookup.

VERDICT: Keep the section and its order, but rewrite its work-item contract around source-relative/import-scope resolution, ADR-compliant match tiers, a measured refreshed-graph denominator, and false-bind invariants. This satisfies SSOT-01, SSOT-04, SSOT-05, and SSOT-15 and avoids LEAK:scattered-knowledge and LEAK:algorithmic-duplication.

[]

DIG DEEPER

scripts/intel-query.sh fitness --json
scripts/intel-query.sh cypher "MATCH (:Symbol {repo:'ori'})-[r:CALLS]->(t) RETURN labels(t)[0],coalesce(r.provenance,'<null>'),coalesce(r.match_tier,'<null>'),count(*)"

(full dossier: call-resolution-tier1-heuristic—s-05f1576d.intel.md)