#Modules
Masterbelt source graphs have a single entrypoint file.
- The entrypoint file is selected by project configuration.
- The entrypoint file is the root used to discover files referenced by the project.
- File identity is resolved internally as a full filesystem path.
- User-facing paths are displayed relative to the project root.
- Hash inputs and other stable user-facing identities use project-root-relative paths.
- Source spans use project-root-relative paths.
#Imports
A use or re-export declaration's from clause carries the module specifier of the foreign module.
Import source strings are resolved as follows:
from "file"resolvesfilerelative to the importing file and appends.mst.from "file.mst"resolvesfile.mstrelative to the importing file.from "file.ext"is invalid whenextis not.mst.- Absolute file import paths are invalid.
from "std:mod"resolves the standard modulestd.mod. Standard modules are reserved for future use; until the standard library is implemented, astd:import reports a diagnostic.- The module name after
std:must match[a-z][a-z0-9_]*.
File imports are internally identified by their full filesystem path. The resolved full filesystem path is used internally for graph operations such as cycle detection.
#Module Graph
The module graph is the set of files reachable from the entrypoint by following use and re-export declarations transitively.
- The entrypoint is loaded first. Every module specifier appearing in a loaded file is then resolved and the target file is loaded, recursively.
- A module specifier that does not resolve to an existing file is a project loading error reported at the importing site.
- A standard-library specifier is rejected at this stage; future iterations will load standard modules from a built-in registry.
- A module that imports itself transitively, including a direct self-import, forms a cycle and is rejected at loading time. The diagnostic is attached to the import that closed the cycle.
The module graph is finite when no cycles exist. The order in which loaded modules become available to the type checker is a topological order: every module's imported modules are checked before the module itself.
#Cross-Module Resolution
After all modules in the graph have been loaded and resolved, the type checker fills in the binding types for the import bindings introduced by use and re-export declarations.
For a named import use { X } from "...":
- If the foreign module declares
pub const Xor re-exportsXas public, the local value-space binding takes the foreign symbol's checked type. - If the foreign module declares
pub type Xor re-exportsXas public, the local type-space binding takes the foreign symbol's resolved target type. - If neither space declares
Xas public in the foreign module, the import is a cross-module resolution error reported at the import site. - A named import that resolves in both spaces is valid; the value-space and the type-space bindings both carry types, and references in either position use the corresponding side.
For a wildcard import use * from "..." or pub * from "...":
- The cross-module phase expands the wildcard into one binding per public symbol the foreign module exposes, under the foreign symbol's name.
- Wildcard expansion happens before checker work for the importing file, so a reference to any expanded name resolves through the normal lookup path.
- A name introduced by wildcard expansion may not collide with another binding in the importing file. The diagnostic is reported on the wildcard declaration.
A re-exporting pub form makes the imported binding part of the current module's public surface. Cross-module lookups against the current module find the re-exported name.
#Cross-File Identifier Uniqueness
Code generation targets may impose project-wide identifier uniqueness as a separate requirement. The language itself only enforces per-file uniqueness in names.md; target-language documents specify when the wider constraint applies and how it is reported.