Re-export and dependency resolution
Almost no real package’s entry file declares its own surface — most just re-export from internal modules. The resolver replays those rewrites until every public symbol points at its terminal declaration. The behaviour visible through the CLI is documented here; the implementation lives in resolver.rs and is internal.
Hops and max_hops
Each follow is one hop. max_hops = 0 parses the entry only and stops. -1 is unlimited. The nci-engine constant DEFAULT_MAX_HOPS is what nci init writes into nci.config.json and what nci index uses when neither the file nor --max-hops says otherwise.
Dependency resolution policy: nci-dep-v1
symbol_dependencies (resolved “uses” edges) follow a fixed precedence — strongest first:
| Layer | Resolution rule |
|---|---|
| 1 | Explicit module specifier on the import statement. |
| 2 | Same file as the using declaration. |
| 3 | Import alias visible in that file. |
| 4 | Files reachable via /// <reference path="…" /> closure. |
| 5 | Weakest: package-wide bare-name fallback. Can tie homonyms — known limitation. |
is_internal does not block an edge — internal symbols still participate in symbol_dependencies.
Two separate edge tables
symbol_dependencies— the resolved graph above, suitable for “what does this declaration reference?”.symbol_surface_dependencies— namespace/module-surface rollup. Don’t use it as a substitute on arbitrary member rows; it answers a different question.
Source package vs. exporting package
When a re-export crosses package boundaries, the resulting symbols row records both ownership layers:
package_idis the indexed install the user typed into the import.source_package_name(andsource_package_versionwhen in-tree) is the package that authored the declaration.
Use source_package_name for nci query --source-package to scope hits to the right ownership layer.
Merge provenance
When the resolver emits two declarations that the dedupe stage decides are “the same”, the row records why:
merge_scope— same merge key as another contribution.identical_fold— samename,kind, normalised signature across external files.overload_key— overload-style merge keyed by normalised signature.
Read these from merge_provenance_json together with signature and kind_name when an overload count looks wrong — overload rows can either fuse into one row or stay distinct depending on normalisation.
Where to go next
- The full schema sits at SQLite schema.
- The graph row shape (including
merge_provenance_json) is at Symbol graph model. - The agent-facing instructions for navigating these edges live in the Agent primer.