Modules & Imports
A Sema module is one .sema file; a package is the tree rooted at a
sema.toml manifest, whose [package] name is the import root. Declarations are
private by default; pub marks the public surface. Imports resolve at compile
time against the lockfile — there are no runtime sys.path surprises, and no
wildcard imports.
Imports
Section titled “Imports”Two forms, both resolved at compile time:
from finops.domain import LedgerEntry, Money # bring specific names inimport finops.policies as policies # bind a whole module (with alias)import a.b.c [as x]binds the module; you call through it (policies.decide(...)).from a.b.c import N1, N2binds specific names directly.- Wildcard imports do not exist — every imported name is explicit (this is what keeps code reviewable and constrained decoding tractable).
- Cyclic imports are compile errors, reported with the package-graph path.
A project splits across files under src/, each addressed as <pkg>.<file>. The
graphrag example is built this way
(types / embed / similarity / store / api / main) to demonstrate a non-monolithic
layout:
from graphrag.embed import embed, projectfrom graphrag.similarity import cosineSee /start/project-layout/ for the directory structure.
Visibility — pub
Section titled “Visibility — pub”Declarations are module-private by default. pub (a soft keyword) marks a
declaration as part of the public surface — a struct, function, trait, or method
other modules may import:
pub struct ReconciliationDecision: entry_id: int matched: bool
pub def reconcile(lines: list[BankLine]) -> list[ReconciliationDecision] !{model.embed}: ...
def candidate_score(bank: BankLine, entry: LedgerEntry) -> f32 !{model.embed}: ... # no `pub` → module-private, invisible to other modulesAccessing a private declaration across modules is a compile error naming the
missing pub. This matters beyond encapsulation: the public signature — the
signature of a pub declaration including its contract clauses and effect row —
is the cache key of Sema’s incremental verification economy, and the module is the
attachment unit for assure grades, module-level policies, and monitor budgets.
Re-export
Section titled “Re-export”Re-export is explicit — there is no implicit passthrough:
pub from finops.domain import Money # re-export Money from this moduleStandard library imports are explicit
Section titled “Standard library imports are explicit”Sema draws a clean line between two orthogonal axes:
- Effect capabilities (
fs,net,code,proc,observe,clock, …) are authorized by the!{...}effect row on a function. That row is already the explicit, governed declaration of what a function may do, so these stay ambient — no import needed. - Standard-library modules (
math,io,http, and thestd.*libraries) are APIs you call. They must be brought in with an explicitimport.
import math # numeric functions + constantsimport io # files + stdiofrom std.belief import Belieffrom std.cache import memoizefrom std.document import Report, renderfrom std.agent_loop import loop_until
x = math.sqrt(2.0) # NameError without `import math`The std.* modules are the standard library written in Sema,
embedded in the compiler and importable everywhere.
Rationale: a program’s library dependencies are legible at the top of the file (as
in Python), and because the name is a bound module handle rather than a magic
global, an optimized implementation can be swapped in behind it later without
touching call sites. Using a library module without importing it is a NameError
with an actionable hint (“module ‘math’ used without import — add import math”), never a silent fallback.
Module initialization
Section titled “Module initialization”Module initialization is deterministic and effect-checked: top-level statements run
once, in dependency order, under the module’s policy attachment. A module whose
initializer needs effects beyond !{} must declare them in the manifest
([package] init_effects), which sema doctor reports.
Grade precedence
Section titled “Grade precedence”Assurance grades attach at three levels, with this precedence:
manifest [assurance] default < module `assure` declaration < per-function @assureSee /neurosymbolic/verification/ for what the grades
(bronze/silver/gold) require.
Failure modes
Section titled “Failure modes”- Unresolvable or cyclic import → compile error with the package-graph path.
- Private access across modules → compile error naming the missing
pub. - Two packages exporting the same root name → manifest aliasing required, never silent shadowing.
- Library module used without
import→NameErrorwith an actionable hint.
What Sema deliberately does not have
Section titled “What Sema deliberately does not have”- Python’s runtime
sys.path/importlibsemantics — undermines the lockfile, replay, and constrained decoding. - Wildcard imports.
- Implicit re-export.
- File-scope
pubgranularity — visibility is per-declaration, which is what the verification cache keys need.
See also
Section titled “See also”- Project Layout — where files and
sema.tomllive. - Standard Library Overview — the
std.*modules. - Functions & Effects — the effect rows that stay ambient.