0%

Section 4: Module System

Goal: Multi-file compilation

SPEC: spec/18-modules.md
DESIGN: design/09-modules/index.md
PROPOSAL: proposals/approved/no-circular-imports-proposal.md — Circular import rejection
PROPOSAL: proposals/approved/module-system-details-proposal.md — Entry points, re-export chains, visibility

Status: In-progress — Core evaluator complete (4.1-4.6), LLVM multi-file infrastructure present (dependency graph, topological sort, symbol mangling), tooling pending (4.7), module details pending (4.8), constants parser done / evaluator pending (4.11), extension parser + basic evaluator done / type checker pending (4.12). Verified 2026-03-29.


4.1 Module Definition


  • Implement: Module structure — spec/18-modules.md § Module Structure

    • Rust Tests: oric/src/imports/tests.rs — 14 tests: path resolution, test module detection, parent module import rules, cycle detection; ori_eval/src/module_registration/tests.rs — 9 tests: function/variant/newtype/impl/extend/def_impl registration
    • Ori Tests: tests/spec/modules/use_imports.ori (13 tests, pub/private functions, types, closures, higher-order functions, config vars)
    • LLVM Support: LLVM codegen for module loading — multi_file.rs infrastructure exists (451 lines, dep graph, topo sort, module-qualified mangling), no integration tests
    • LLVM Rust Tests: ori_llvm/tests/module_tests.rs — module loading codegen (file does not exist)
    • AOT Tests: No AOT coverage yet
  • Implement: Module corresponds to file — spec/18-modules.md § Module Structure

    • Rust Tests: oric/src/imports/mod.rs::resolve_relative_import_tracked() — probes <path>.ori then <path>/mod.ori
    • Ori Tests: tests/spec/modules/_test/directory_module.test.ori — directory module resolution
  • Implement: Module name from file path — spec/18-modules.md § Module Structure

    • Rust Tests: oric/src/imports/tests.rsgenerate_relative_candidates_file_module, _parent_path, _nested_directory, _with_extension (4 tests); ori_llvm/src/aot/multi_file/tests.rsderive_module_name (3 tests)
    • Ori Tests: N/A (tested via Rust unit tests)
  • /tpr-review passed — independent review found no critical or major issues (or all findings triaged)

  • /impl-hygiene-review passed — hygiene review clean. MUST run AFTER /tpr-review is clean.

  • Subsection close-out (4.1) — MANDATORY before starting the next subsection. Run /improve-tooling retrospectively on THIS subsection’s debugging journey (per .claude/skills/improve-tooling/SKILL.md “Per-Subsection Workflow”): which diagnostics/ scripts you ran, where you added dbg!/tracing calls, where output was hard to interpret, where test failures gave unhelpful messages, where you ran the same command sequence repeatedly. Forward-look: what tool/log/diagnostic would shorten the next regression in this code path by 10 minutes? Implement improvements NOW (zero deferral) and commit each via SEPARATE /commit-push using a valid conventional-commit type (build(diagnostics): ... — surfaced by section-4.1 retrospectivebuild/test/chore/ci/docs are valid; tools(...) is rejected by the lefthook commit-msg hook). Mandatory even when nothing felt painful. If genuinely no gaps, document briefly: “Retrospective 4.1: no tooling gaps”. Update this subsection’s status in section frontmatter to complete.

  • /sync-claude section-close doc sync — verify Claude artifacts across all section commits. Map changed crates to rules files, check CLAUDE.md, canon.md. Fix drift NOW.

  • Repo hygiene check — run diagnostics/repo-hygiene.sh --check and clean any detected temp files.

4.2 Import Parsing

Relative imports:

Module imports:

Private imports:

Aliases:


  • Implement: use './path' { item1, item2 } — spec/18-modules.md § Relative Imports

    • Rust Tests: oric/src/imports/tests.rs — path resolution tests
    • Ori Tests: tests/spec/modules/_test/use_imports.test.ori (4 tests: add, make_multiplier, calculate, double)
  • Implement: Parent use '../utils' { helper } — spec/18-modules.md § Relative Imports

    • Rust Tests: oric/src/imports/tests.rs::generate_relative_candidates_parent_path
    • Ori Tests: tests/spec/modules/_test/use_imports.test.ori (uses "../use_imports")
  • Implement: Subdirectory use './http/client' { get } — spec/18-modules.md § Relative Imports WEAK TESTS

    • Rust Tests: oric/src/imports/tests.rs::generate_relative_candidates_nested_directory
    • Ori Tests: N/A (tested via Rust unit tests only)
    • Gap: Need Ori spec test for subdirectory relative imports (currently Rust unit test only, no end-to-end .ori test)
  • Implement: use std.module { item } — spec/18-modules.md § Module Imports

    • Rust Tests: oric/src/imports/tests.rs::resolve_module_path_not_found — stdlib path resolution
    • Ori Tests: 415 of 882 spec/library .ori files use std.testing (406 import { assert_eq })
  • Implement: Nested use std.net.http { get } — spec/18-modules.md § Module Imports

    • Rust Tests: Parser supports multi-segment paths (verified via test_import_without_def_basic); no runtime test
    • Ori Tests: N/A — no nested stdlib modules exist yet to test
  • Implement: use './path' { ::private_item } — spec/18-modules.md § Private Imports

    • Rust Tests: oric/tests/phases/parse/imports.rs::test_import_private_basic, test_import_private_with_alias
    • Ori Tests: tests/spec/modules/_test/use_private.test.ori (2 tests: private fn access, private + public combo)
  • Implement: :: prefix — spec/18-modules.md § Private Imports

    • Rust Tests: Parser tests verify items[0].is_private flag set for :: prefix
    • Ori Tests: tests/spec/modules/_test/use_private.test.ori
  • Implement: use './math' { add as plus } — spec/18-modules.md § Aliases

    • Rust Tests: ori_parse/src/grammar/ — alias parsing
    • Ori Tests: tests/spec/modules/_test/use_aliases.test.ori (3 tests: add as plus, make_multiplier as create_multiplier, double as twice)
  • Implement: Module alias use std.net.http as http — spec/18-modules.md § Aliases

    • Rust Tests: ori_parse/src/grammar/ — module alias parsing
    • Ori Tests: tests/spec/modules/_test/module_alias.test.ori (11 tests: qualified access math.add(), math.subtract(), math.multiply(), math.square(), math.double(), math.make_adder(), math.use_internal())
    • Note: Parsing and runtime complete; qualified access works via evaluator. Type checker ModuleNamespace support pending.
  • /tpr-review passed — independent review found no critical or major issues (or all findings triaged)

  • /impl-hygiene-review passed — hygiene review clean. MUST run AFTER /tpr-review is clean.

  • Subsection close-out (4.2) — MANDATORY before starting the next subsection. Run /improve-tooling retrospectively on THIS subsection’s debugging journey (per .claude/skills/improve-tooling/SKILL.md “Per-Subsection Workflow”): which diagnostics/ scripts you ran, where you added dbg!/tracing calls, where output was hard to interpret, where test failures gave unhelpful messages, where you ran the same command sequence repeatedly. Forward-look: what tool/log/diagnostic would shorten the next regression in this code path by 10 minutes? Implement improvements NOW (zero deferral) and commit each via SEPARATE /commit-push using a valid conventional-commit type (build(diagnostics): ... — surfaced by section-4.2 retrospectivebuild/test/chore/ci/docs are valid; tools(...) is rejected by the lefthook commit-msg hook). Mandatory even when nothing felt painful. If genuinely no gaps, document briefly: “Retrospective 4.2: no tooling gaps”. Update this subsection’s status in section frontmatter to complete.

  • /sync-claude section-close doc sync — verify Claude artifacts across all section commits. Map changed crates to rules files, check CLAUDE.md, canon.md. Fix drift NOW.

  • Repo hygiene check — run diagnostics/repo-hygiene.sh --check and clean any detected temp files.

4.3 Visibility


  • Implement: pub on functions — spec/18-modules.md § Visibility

    • Rust Tests: ori_parse/src/grammar/pub keyword parsing
    • Ori Tests: tests/spec/modules/use_imports.ori (9 pub functions); _test/use_imports.test.ori imports 4 of them
  • Implement: pub on types — spec/18-modules.md § Visibility WEAK TESTS

    • Rust Tests: ori_parse/src/grammar/ — type visibility parsing
    • Ori Tests: library/std/prelude.oripub type Option, pub type Result; use_imports.ori has pub type Point
    • Gap: No cross-module type import test — pub type Point is declared but never imported in a cross-module test
  • Implement: pub on config variables — spec/18-modules.md § Visibility [partial] INCOMPLETE

    • Parser: Config visibility parsing works — 6 parser tests in oric/tests/phases/parse/imports.rs
    • Ori Declaration: tests/spec/modules/use_imports.ori (pub $default_timeout, private $internal_limit)
    • Evaluator: Constant import resolution NOT implemented — _test/use_constants.test.ori is #skip("constant import resolution not yet implemented")
    • Note: Parser done, evaluator not done. Previously marked [x] incorrectly — reopened
  • Implement: Re-exports pub use — spec/18-modules.md § Re-exports WEAK TESTS

    • Rust Tests: ori_parse/src/grammar/ — re-export parsing
    • Ori Tests: tests/spec/modules/reexporter.ori (pub use "./math_lib" { add, multiply }, self-test only)
    • Gap: No cross-module re-export consumption test — reexporter.ori tests itself but no file imports from it
    • Note: Basic re-export works; multi-level chain resolution pending (4.8)
  • Implement: Private by default — spec/18-modules.md § Visibility NEEDS PIN

    • Rust Tests: oric/src/imports/tests.rs — visibility enforcement
    • Ori Tests: tests/spec/modules/_test/use_private.test.ori (private access with :: prefix)
    • Gap: No #compile_fail test for importing a private item without :: from a non-test module
  • /tpr-review passed — independent review found no critical or major issues (or all findings triaged)

  • /impl-hygiene-review passed — hygiene review clean. MUST run AFTER /tpr-review is clean.

  • Subsection close-out (4.3) — MANDATORY before starting the next subsection. Run /improve-tooling retrospectively on THIS subsection’s debugging journey (per .claude/skills/improve-tooling/SKILL.md “Per-Subsection Workflow”): which diagnostics/ scripts you ran, where you added dbg!/tracing calls, where output was hard to interpret, where test failures gave unhelpful messages, where you ran the same command sequence repeatedly. Forward-look: what tool/log/diagnostic would shorten the next regression in this code path by 10 minutes? Implement improvements NOW (zero deferral) and commit each via SEPARATE /commit-push using a valid conventional-commit type (build(diagnostics): ... — surfaced by section-4.3 retrospectivebuild/test/chore/ci/docs are valid; tools(...) is rejected by the lefthook commit-msg hook). Mandatory even when nothing felt painful. If genuinely no gaps, document briefly: “Retrospective 4.3: no tooling gaps”. Update this subsection’s status in section frontmatter to complete.

  • /sync-claude section-close doc sync — verify Claude artifacts across all section commits. Map changed crates to rules files, check CLAUDE.md, canon.md. Fix drift NOW.

  • Repo hygiene check — run diagnostics/repo-hygiene.sh --check and clean any detected temp files.

4.4 Module Resolution


  • Implement: File path resolution — spec/18-modules.md § Module Resolution

    • Rust Tests: oric/src/imports/tests.rs — 4 candidate generation tests (generate_relative_candidates_*)
    • Ori Tests: tests/spec/modules/_test/directory_module.test.ori (2 tests), _test/precedence.test.ori (file precedence over dir)
  • Implement: Module dependency graph — spec/18-modules.md § Dependency Graph

    • Rust Tests: oric/src/imports/tests.rsLoadingContext cycle detection; ori_llvm/src/aot/incremental/deps/tests.rs — 12 tests
    • Ori Tests: N/A (tested via Rust unit tests)
    • Note: Both eval (via Salsa) and LLVM (explicit DependencyGraph) have dependency tracking with tests
  • Implement: Cycle detection — spec/18-modules.md § Cycle Detection, proposals/approved/no-circular-imports-proposal.md

    • Rust Tests: oric/src/imports/tests.rsloading_context_cycle_detection, loading_context_cycle_error; ori_llvm/src/aot/multi_file/tests.rs::test_graph_build_context_cycle_detection
    • Ori Tests: N/A (tested via Rust unit tests)
    • Note: Both eval and LLVM backends have cycle detection
  • Implement: Enhanced cycle error messages — proposals/approved/no-circular-imports-proposal.md § Error Message

    • Show full cycle path in error (a.ori -> b.ori -> a.ori)
    • Include actionable help: “extract shared types”, “use dependency inversion”, “restructure boundaries”
    • Rust Tests: oric/src/imports/tests.rs — cycle error formatting tests
    • Ori Tests: tests/spec/modules/cycle_error_message.ori
  • Implement: Report all cycles (not just first) — proposals/approved/no-circular-imports-proposal.md § Detection Algorithm

    • Continue detection after finding first cycle
    • Report each cycle with full path
    • Rust Tests: oric/src/imports/tests.rs — multi-cycle detection tests
    • Ori Tests: tests/spec/modules/multiple_cycles.ori
  • Implement: Name resolution — spec/18-modules.md § Name Resolution

    • Rust Tests: All import test files exercise name resolution
    • Ori Tests: All import tests verify name resolution (use_imports, use_private, use_aliases, module_alias)
  • Implement: Qualified access — spec/18-modules.md § Qualified Accessevaluator

    • Rust Tests: Qualified access evaluation tested via module_alias tests
    • Ori Tests: tests/spec/modules/_test/module_alias.test.ori (11 tests: math.add(), math.multiply(), etc.)
    • LLVM Support: LLVM codegen for qualified access dispatch — multi_file.rs has module-qualified mangling (_ori_<module>$<function>)
    • LLVM Rust Tests: ori_llvm/tests/module_tests.rs — qualified access codegen (file does not exist)
    • AOT Tests: No AOT coverage yet
    • Note: Runtime evaluation complete; type checker needs ModuleNamespace support
  • /tpr-review passed — independent review found no critical or major issues (or all findings triaged)

  • /impl-hygiene-review passed — hygiene review clean. MUST run AFTER /tpr-review is clean.

  • Subsection close-out (4.4) — MANDATORY before starting the next subsection. Run /improve-tooling retrospectively on THIS subsection’s debugging journey (per .claude/skills/improve-tooling/SKILL.md “Per-Subsection Workflow”): which diagnostics/ scripts you ran, where you added dbg!/tracing calls, where output was hard to interpret, where test failures gave unhelpful messages, where you ran the same command sequence repeatedly. Forward-look: what tool/log/diagnostic would shorten the next regression in this code path by 10 minutes? Implement improvements NOW (zero deferral) and commit each via SEPARATE /commit-push using a valid conventional-commit type (build(diagnostics): ... — surfaced by section-4.4 retrospectivebuild/test/chore/ci/docs are valid; tools(...) is rejected by the lefthook commit-msg hook). Mandatory even when nothing felt painful. If genuinely no gaps, document briefly: “Retrospective 4.4: no tooling gaps”. Update this subsection’s status in section frontmatter to complete.

  • /sync-claude section-close doc sync — verify Claude artifacts across all section commits. Map changed crates to rules files, check CLAUDE.md, canon.md. Fix drift NOW.

  • Repo hygiene check — run diagnostics/repo-hygiene.sh --check and clean any detected temp files.

4.5 Test Modules


  • Implement: _test/ convention — spec/18-modules.md § Test Modules

    • Rust Tests: oric/src/imports/tests.rs — 4 is_test_module tests: valid, not_in_test_dir, wrong_extension, nested
    • Ori Tests: tests/spec/modules/_test/test_module_access.test.ori (2 tests)
  • Implement: Test files access private items — spec/18-modules.md § Test Modules

    • Rust Tests: oric/src/imports/tests.rs — 3 is_parent_module_import tests
    • Ori Tests: tests/spec/modules/_test/test_module_access.test.ori (accesses private internal_helper without :: prefix)

4.6 Prelude


  • Implement: Types: Option, Result, Error, Ordering — spec/18-modules.md § Prelude

    • Rust Tests: ori_eval/src/interpreter/ — built-in type tests
    • Ori Tests: Option/Result used throughout the spec test suite (882 .ori files under tests/+library/), Ordering verified in tests/spec/types/ordering/
    • LLVM Support: LLVM codegen for prelude type representations — Option/Result have inline IR in lower_calls.rs
    • LLVM Rust Tests: ori_llvm/tests/module_tests.rs — prelude type codegen (file does not exist)
    • AOT Tests: No AOT coverage yet
  • Implement: Built-in functions: print, panic, int, float, str, byte — spec/18-modules.md § Prelude

    • Rust Tests: register_prelude() registers 8 function_vals; print/panic registered separately
    • Ori Tests: Built-ins used throughout test suite
    • LLVM Support: LLVM codegen for built-in functions — print via _ori_print, panic via _ori_panic, conversions via inline IR
    • LLVM Rust Tests: ori_llvm/tests/module_tests.rs — built-in function codegen (file does not exist)
    • AOT Tests: No AOT coverage yet
  • Implement: Built-in methods: .len(), .is_empty(), .is_some(), etc. — Lean Core

    • Rust Tests: ori_eval/src/methods.rs — method dispatch tests
    • Ori Tests: tests/spec/traits/core/ — len (14 tests), comparable (58 tests); tests/spec/types/ — option, result tests
    • LLVM Support: LLVM codegen for built-in methods — inline IR in lower_calls.rs (len, is_empty, is_some, is_none, unwrap, unwrap_or, is_ok, is_err, compare)
    • LLVM Rust Tests: ori_llvm/tests/module_tests.rs — built-in method codegen (file does not exist)
    • AOT Tests: No AOT coverage yet
  • Implement: Auto-import prelude from library/std/prelude.ori — spec/18-modules.md § Prelude

    • resolve_imports() loads prelude via prelude_candidates() walk-up search
    • All public functions from prelude available without import
    • Rust Tests: ori_eval/src/interpreter/ — prelude loading tests
    • Ori Tests: 415 of 882 spec/library .ori files use std.testing (406 import { assert_eq }), which depends on prelude
    • LLVM Support: LLVM codegen for prelude auto-loading
    • LLVM Rust Tests: ori_llvm/tests/module_tests.rs — prelude loading codegen (file does not exist)
    • AOT Tests: No AOT coverage yet
  • Implement: Prelude functions auto-available

    • assert, assert_eq, assert_ne, assert_some, assert_none, assert_ok, assert_err
    • is_some, is_none, is_ok, is_err
    • len, is_empty
    • compare, min, max
    • LLVM Support: LLVM codegen for prelude functions — partial (print, panic, len, compare have IR; assert_* not yet)
    • LLVM Rust Tests: ori_llvm/tests/module_tests.rs — prelude function codegen (file does not exist)
    • AOT Tests: No AOT coverage yet
    • Note: Trait definitions in prelude (Eq, Comparable, etc.) parse but need Section 3 for full integration
  • /tpr-review passed — independent review found no critical or major issues (or all findings triaged)

  • /impl-hygiene-review passed — hygiene review clean. MUST run AFTER /tpr-review is clean.

  • Subsection close-out (4.6) — MANDATORY before starting the next subsection. Run /improve-tooling retrospectively on THIS subsection’s debugging journey (per .claude/skills/improve-tooling/SKILL.md “Per-Subsection Workflow”): which diagnostics/ scripts you ran, where you added dbg!/tracing calls, where output was hard to interpret, where test failures gave unhelpful messages, where you ran the same command sequence repeatedly. Forward-look: what tool/log/diagnostic would shorten the next regression in this code path by 10 minutes? Implement improvements NOW (zero deferral) and commit each via SEPARATE /commit-push using a valid conventional-commit type (build(diagnostics): ... — surfaced by section-4.6 retrospectivebuild/test/chore/ci/docs are valid; tools(...) is rejected by the lefthook commit-msg hook). Mandatory even when nothing felt painful. If genuinely no gaps, document briefly: “Retrospective 4.6: no tooling gaps”. Update this subsection’s status in section frontmatter to complete.

  • /sync-claude section-close doc sync — verify Claude artifacts across all section commits. Map changed crates to rules files, check CLAUDE.md, canon.md. Fix drift NOW.

  • Repo hygiene check — run diagnostics/repo-hygiene.sh --check and clean any detected temp files.

4.7 Import Graph Tooling

PROPOSAL: proposals/approved/no-circular-imports-proposal.md § Tooling Support


  • Implement: ori check --cycles — Check for cycles without full compilation

    • Fast path: parse imports only, build graph, detect cycles
    • Rust Tests: oric/src/commands/ — cycle checking tests
    • Ori Tests: tests/cli/check_cycles.ori
  • Implement: ori graph --imports — Visualize import graph

    • Output DOT format for graphviz
    • Usage: ori graph --imports > imports.dot && dot -Tpng imports.dot -o imports.png
    • Rust Tests: oric/src/commands/ — graph output tests
    • Ori Tests: tests/cli/graph_imports.ori
  • /tpr-review passed — independent review found no critical or major issues (or all findings triaged)

  • /impl-hygiene-review passed — hygiene review clean. MUST run AFTER /tpr-review is clean.

  • Subsection close-out (4.7) — MANDATORY before starting the next subsection. Run /improve-tooling retrospectively on THIS subsection’s debugging journey (per .claude/skills/improve-tooling/SKILL.md “Per-Subsection Workflow”): which diagnostics/ scripts you ran, where you added dbg!/tracing calls, where output was hard to interpret, where test failures gave unhelpful messages, where you ran the same command sequence repeatedly. Forward-look: what tool/log/diagnostic would shorten the next regression in this code path by 10 minutes? Implement improvements NOW (zero deferral) and commit each via SEPARATE /commit-push using a valid conventional-commit type (build(diagnostics): ... — surfaced by section-4.7 retrospectivebuild/test/chore/ci/docs are valid; tools(...) is rejected by the lefthook commit-msg hook). Mandatory even when nothing felt painful. If genuinely no gaps, document briefly: “Retrospective 4.7: no tooling gaps”. Update this subsection’s status in section frontmatter to complete.

  • /sync-claude section-close doc sync — verify Claude artifacts across all section commits. Map changed crates to rules files, check CLAUDE.md, canon.md. Fix drift NOW.

  • Repo hygiene check — run diagnostics/repo-hygiene.sh --check and clean any detected temp files.

4.8 Module System Details

PROPOSAL: proposals/approved/module-system-details-proposal.md

Entry Point Files

  • Implement: lib.ori as library entry point — spec/18-modules.md § Entry Point Files

    • Rust Tests: ori_eval/src/interpreter/module/ — library entry detection
    • Ori Tests: tests/spec/modules/library_entry.ori
  • Implement: Distinguish lib.ori vs mod.ori — spec/18-modules.md § Entry Point Files

    • Package root requires lib.ori, not mod.ori
    • Rust Tests: ori_eval/src/interpreter/module/ — entry point validation
    • Ori Tests: tests/spec/modules/entry_point_validation.ori

Binary-Library Separation

  • Implement: Binary accesses library via public API only — spec/18-modules.md § Library + Binary

    • use "my_pkg" { item } accesses lib.ori exports
    • use "my_pkg" { ::private } is an error (no private access)
    • Rust Tests: ori_eval/src/interpreter/module/ — binary-library access tests
    • Ori Tests: tests/spec/modules/binary_library_access.ori

Re-export Chains

  • Implement: Multi-level re-export resolution — spec/18-modules.md § Re-export Chains

    • Track visibility through chain (all levels must be pub)
    • Aliases propagate through chains
    • Rust Tests: ori_eval/src/interpreter/module/ — re-export chain tests
    • Ori Tests: tests/spec/modules/reexport_chain.ori
  • Implement: Diamond re-exports — spec/18-modules.md § Re-export Chains

    • Same item via multiple paths is not an error
    • Rust Tests: ori_eval/src/interpreter/module/ — diamond import tests
    • Ori Tests: tests/spec/modules/diamond_reexport.ori

Error Messages


  • Implement: E1101 (missing module) — proposals/approved/module-system-details-proposal.md § Error Messages

    • Show paths checked: file.ori, file/mod.ori
    • Rust Tests: ori_diagnostic/src/ — error formatting tests
    • Ori Tests: tests/spec/modules/error_missing_module.ori
  • Implement: E1102 (missing export) — proposals/approved/module-system-details-proposal.md § Error Messages

    • Show available exports in error message
    • “Did you mean?” suggestion
    • Rust Tests: ori_diagnostic/src/ — error formatting tests
    • Ori Tests: tests/spec/modules/error_missing_export.ori
  • Implement: E1103 (private item) — proposals/approved/module-system-details-proposal.md § Error Messages

    • Help text: “use ::item for explicit private access”
    • Rust Tests: ori_diagnostic/src/ — error formatting tests
    • Ori Tests: tests/spec/modules/error_private_item.ori
  • /tpr-review passed — independent review found no critical or major issues (or all findings triaged)

  • /impl-hygiene-review passed — hygiene review clean. MUST run AFTER /tpr-review is clean.

  • Subsection close-out (4.8) — MANDATORY before starting the next subsection. Run /improve-tooling retrospectively on THIS subsection’s debugging journey (per .claude/skills/improve-tooling/SKILL.md “Per-Subsection Workflow”): which diagnostics/ scripts you ran, where you added dbg!/tracing calls, where output was hard to interpret, where test failures gave unhelpful messages, where you ran the same command sequence repeatedly. Forward-look: what tool/log/diagnostic would shorten the next regression in this code path by 10 minutes? Implement improvements NOW (zero deferral) and commit each via SEPARATE /commit-push using a valid conventional-commit type (build(diagnostics): ... — surfaced by section-4.8 retrospectivebuild/test/chore/ci/docs are valid; tools(...) is rejected by the lefthook commit-msg hook). Mandatory even when nothing felt painful. If genuinely no gaps, document briefly: “Retrospective 4.8: no tooling gaps”. Update this subsection’s status in section frontmatter to complete.

  • /sync-claude section-close doc sync — verify Claude artifacts across all section commits. Map changed crates to rules files, check CLAUDE.md, canon.md. Fix drift NOW.

  • Repo hygiene check — run diagnostics/repo-hygiene.sh --check and clean any detected temp files.

4.9 Remaining Work (Pre-existing)

Parsing/Runtime complete, type checker pending:


  • Module alias syntax: use "../math_lib" as math — parsing, runtime

  • Re-exports: pub use './client' { get, post } — basic parsing, basic resolution WEAK TESTS

    • Gap: No cross-module re-export consumption test
  • Qualified access: module.function() — runtime

  • Type checker ModuleNamespace support — pending

  • Multi-level re-export chain resolution — pending (4.8)

  • Nested stdlib modules (std.net.http) — no modules to test yet

  • /tpr-review passed — independent review found no critical or major issues (or all findings triaged)

  • /impl-hygiene-review passed — hygiene review clean. MUST run AFTER /tpr-review is clean.

  • Subsection close-out (4.9) — MANDATORY before starting the next subsection. Run /improve-tooling retrospectively on THIS subsection’s debugging journey (per .claude/skills/improve-tooling/SKILL.md “Per-Subsection Workflow”): which diagnostics/ scripts you ran, where you added dbg!/tracing calls, where output was hard to interpret, where test failures gave unhelpful messages, where you ran the same command sequence repeatedly. Forward-look: what tool/log/diagnostic would shorten the next regression in this code path by 10 minutes? Implement improvements NOW (zero deferral) and commit each via SEPARATE /commit-push using a valid conventional-commit type (build(diagnostics): ... — surfaced by section-4.9 retrospectivebuild/test/chore/ci/docs are valid; tools(...) is rejected by the lefthook commit-msg hook). Mandatory even when nothing felt painful. If genuinely no gaps, document briefly: “Retrospective 4.9: no tooling gaps”. Update this subsection’s status in section frontmatter to complete.

  • /sync-claude section-close doc sync — verify Claude artifacts across all section commits. Map changed crates to rules files, check CLAUDE.md, canon.md. Fix drift NOW.

  • Repo hygiene check — run diagnostics/repo-hygiene.sh --check and clean any detected temp files.

4.11 Module-Level Constants

Source: grammar.ebnf § constant_decl, spec/12-constants.md

Module-level constants declared with let $NAME = value.

let $PI = 3.14159
let $MAX_SIZE: int = 1000
pub let $VERSION = "1.0.0"

Status: Parser complete, evaluator incomplete.

Parser

  • Implement: Parse let $NAME = valueconstant_decl production

    • Rust Tests: compiler/ori_parse/src/grammar/item/config/mod.rsparse_const() implementation; oric/tests/phases/parse/imports.rstest_import_constant_basic, _multiple, _mixed_with_regular, _mixed_with_private (6 tests)
    • Ori Tests: tests/spec/modules/use_imports.ori — declares pub $default_timeout = 30 and $internal_limit = 100
  • Implement: Parse typed constants let $NAME: Type = value

    • Rust Tests: oric/tests/phases/parse/imports.rs — constant parsing tests cover typed forms
  • Implement: Parse public constants pub let $NAME = value

    • Rust Tests: oric/tests/phases/parse/imports.rs — visibility parsing for constants

Evaluator

  • Implement: Evaluate module-level constants at load time

    • Rust Tests: ori_eval/src/interpreter/mod.rs — constant evaluation
    • Ori Tests: tests/spec/declarations/constants_eval.ori
    • LLVM Support: LLVM codegen for module constants
    • LLVM Rust Tests: ori_llvm/tests/constant_tests.rs
    • AOT Tests: No AOT coverage yet
  • Implement: Register constants in module namespace

    • Rust Tests: ori_eval/src/interpreter/module_loading.rs — constant registration
    • Ori Tests: tests/spec/modules/import_constants.ori

Type Checker

  • Implement: Type check constant initializers

    • Rust Tests: ori_types/src/check/ — constant type checking
    • Ori Tests: tests/spec/types/constant_types.ori
  • Implement: Enforce constant expression restrictions (no function calls with side effects)

    • Rust Tests: ori_types/src/check/ — constant expression validation
    • Ori Compile-Fail Tests: tests/compile-fail/constant_non_const_expr.ori

Import/Export


  • Implement: Export constants via pub let

    • Ori Tests: tests/spec/modules/export_constants.ori
  • Implement: Import constants via use "path" { $CONST }

    • Ori Tests: tests/spec/modules/import_constants.ori
  • /tpr-review passed — independent review found no critical or major issues (or all findings triaged)

  • /impl-hygiene-review passed — hygiene review clean. MUST run AFTER /tpr-review is clean.

  • Subsection close-out (4.11) — MANDATORY before starting the next subsection. Run /improve-tooling retrospectively on THIS subsection’s debugging journey (per .claude/skills/improve-tooling/SKILL.md “Per-Subsection Workflow”): which diagnostics/ scripts you ran, where you added dbg!/tracing calls, where output was hard to interpret, where test failures gave unhelpful messages, where you ran the same command sequence repeatedly. Forward-look: what tool/log/diagnostic would shorten the next regression in this code path by 10 minutes? Implement improvements NOW (zero deferral) and commit each via SEPARATE /commit-push using a valid conventional-commit type (build(diagnostics): ... — surfaced by section-4.11 retrospectivebuild/test/chore/ci/docs are valid; tools(...) is rejected by the lefthook commit-msg hook). Mandatory even when nothing felt painful. If genuinely no gaps, document briefly: “Retrospective 4.11: no tooling gaps”. Update this subsection’s status in section frontmatter to complete.

  • /sync-claude section-close doc sync — verify Claude artifacts across all section commits. Map changed crates to rules files, check CLAUDE.md, canon.md. Fix drift NOW.

  • Repo hygiene check — run diagnostics/repo-hygiene.sh --check and clean any detected temp files.

4.12 Extension Methods

PROPOSAL: proposals/approved/extension-methods-proposal.md

Extension methods add methods to existing types without modifying their definition.

Status: Parser and basic evaluator complete. Type checker integration, conflict detection, orphan rules, error codes (E0850-E0852), LLVM codegen pending.

Extension Definition

  • Implement: extend Type { @method (self) -> T = ... } — proposals/approved/extension-methods-proposal.md § Extension Definition [partial]

    • Parse extend blocks — compiler/ori_parse/src/grammar/item/extend.rs
    • Register extension methods in type environment — ori_eval/src/module_registration/tests.rs has test_collect_extend_methods and test_collect_extend_methods_with_config (2 tests)
    • Rust Tests: oric/tests/phases/parse/extensions.rs — 12 parser tests: extend with where clause, multiple bounds, multiple methods, extension import variants
    • Ori Tests: tests/spec/extensions/list_methods.ori — end-to-end test with extend str { @shout, @whisper } and extend [T] { @count, @empty }
    • Type Checker: Type checker integration for extension method resolution — not implemented
    • Conflict Detection: Conflict detection for ambiguous extension methods — not implemented
  • Implement: Constrained extensions with angle brackets — proposals/approved/extension-methods-proposal.md § Constrained Extensions

    • Parse extend<T: Clone> [T] { ... } syntax — parser supports this
    • Type checker constraint enforcement
    • Ori Tests: tests/spec/extensions/constrained.ori
  • Implement: Constrained extensions with where clause — proposals/approved/extension-methods-proposal.md § Constrained Extensions

    • Parse extend [T] where T: Clone { ... } syntax — parser supports this
    • Type checker where clause enforcement
    • Ori Tests: tests/spec/extensions/constrained_where.ori
  • Implement: Extension visibility — proposals/approved/extension-methods-proposal.md § Visibility

    • pub extend makes all methods public
    • Non-pub extend is module-private
    • Block-level visibility only (no per-method pub)
    • Rust Tests: ori_eval/src/interpreter/module/ — visibility tests
    • Ori Tests: tests/spec/extensions/visibility.ori
  • Implement: Extension restrictions — proposals/approved/extension-methods-proposal.md § What Can Be Extended

    • Error on field addition attempt
    • Error on trait implementation in extend block
    • Error on override of existing method
    • Error on static method (no self)
    • Rust Tests: ori_diagnostic/src/ — restriction error tests
    • Ori Tests: tests/spec/extensions/restrictions.ori

Extension Import

  • Implement: extension "path" { Type.method } — proposals/approved/extension-methods-proposal.md § Extension Import [partial]

    • Parse extension import syntax — compiler/ori_parse/src/grammar/item/extension_import.rs
    • Method-level granularity — parser enforces method-level granularity
    • Rust Tests: oric/tests/phases/parse/extensions.rs — extension import tests: basic, multiple items, relative path, public, private, with regular imports, multiple types, missing dot error
    • Ori Tests: tests/spec/extensions/import.ori — end-to-end extension import test (not yet created)
    • Runtime: Extension import resolution in evaluator — not implemented
  • Implement: Wildcard prohibition — proposals/approved/extension-methods-proposal.md § Import Syntax

    • Error on extension "path" { Type.* }
    • Rust Tests: ori_diagnostic/src/ — wildcard error tests
    • Ori Tests: tests/spec/extensions/no_wildcard.ori
  • Implement: Re-export extensions — proposals/approved/extension-methods-proposal.md § Scoping

    • pub extension "path" { Type.method } for re-export
    • No transitive propagation without explicit re-export
    • Rust Tests: ori_eval/src/interpreter/module/ — re-export tests
    • Ori Tests: tests/spec/extensions/reexport.ori

Method Resolution

  • Implement: Resolution order — proposals/approved/extension-methods-proposal.md § Resolution Order

    • Inherent > Trait > Extension
    • Rust Tests: ori_types/src/check/ — resolution order tests
    • Ori Tests: tests/spec/extensions/resolution_order.ori
  • Implement: Conflict detection — proposals/approved/extension-methods-proposal.md § Conflict Resolution

    • Error on ambiguous extension methods
    • Qualified syntax for disambiguation: module.Type.method(v)
    • Rust Tests: ori_types/src/check/ — conflict detection tests
    • Ori Tests: tests/spec/extensions/conflict.ori

Orphan Rules

  • Implement: Same-package rule — proposals/approved/extension-methods-proposal.md § Orphan Rules

    • Extension must be in same package as type OR trait bound
    • Error for foreign type without local trait bound
    • Rust Tests: ori_types/src/check/ — orphan rule tests
    • Ori Tests: tests/spec/extensions/orphan.ori

Error Messages

  • Implement: E0850 (ambiguous extension) — proposals/approved/extension-methods-proposal.md § Error Messages

    • Show all candidate extensions
    • Help text for qualified syntax
    • Rust Tests: ori_diagnostic/src/ — error formatting tests
    • Ori Tests: tests/spec/extensions/error_ambiguous.ori
  • Implement: E0851 (method not found) — proposals/approved/extension-methods-proposal.md § Error Messages

    • Suggest extension import if method exists in known module
    • Rust Tests: ori_diagnostic/src/ — error formatting tests
    • Ori Tests: tests/spec/extensions/error_not_found.ori
  • Implement: E0852 (orphan violation) — proposals/approved/extension-methods-proposal.md § Error Messages

    • Show package location of foreign type
    • Help: “define a newtype wrapper or use a local trait bound”
    • Rust Tests: ori_diagnostic/src/ — error formatting tests
    • Ori Tests: tests/spec/extensions/error_orphan.ori

LLVM Support

Note on Type Definitions:

  • Full prelude with user-defined Option, Result, etc. requires Section 5 (Type Declarations)
  • Currently using built-in types in evaluator
  • See section-05-type-declarations.md § 5.1-5.4 for type definition work

  • Implement: Extension method codegen — Extension methods in LLVM backend

    • Same codegen as regular methods
    • LLVM Rust Tests: ori_llvm/tests/extension_tests.rs
    • AOT Tests: No AOT coverage yet
  • /tpr-review passed — independent review found no critical or major issues (or all findings triaged)

  • /impl-hygiene-review passed — hygiene review clean. MUST run AFTER /tpr-review is clean.

  • Subsection close-out (4.12) — MANDATORY before starting the next subsection. Run /improve-tooling retrospectively on THIS subsection’s debugging journey (per .claude/skills/improve-tooling/SKILL.md “Per-Subsection Workflow”): which diagnostics/ scripts you ran, where you added dbg!/tracing calls, where output was hard to interpret, where test failures gave unhelpful messages, where you ran the same command sequence repeatedly. Forward-look: what tool/log/diagnostic would shorten the next regression in this code path by 10 minutes? Implement improvements NOW (zero deferral) and commit each via SEPARATE /commit-push using a valid conventional-commit type (build(diagnostics): ... — surfaced by section-4.12 retrospectivebuild/test/chore/ci/docs are valid; tools(...) is rejected by the lefthook commit-msg hook). Mandatory even when nothing felt painful. If genuinely no gaps, document briefly: “Retrospective 4.12: no tooling gaps”. Update this subsection’s status in section frontmatter to complete.

  • /sync-claude section-close doc sync — verify Claude artifacts across all section commits. Map changed crates to rules files, check CLAUDE.md, canon.md. Fix drift NOW.

  • Repo hygiene check — run diagnostics/repo-hygiene.sh --check and clean any detected temp files.

4.10 Section Completion Checklist

Exit Criteria: Multi-file projects compile (core support complete) Status: Section 4 evaluator and parser complete. 27 of 35 [x] items fully verified, 4 have weak tests, 1 incomplete (config var imports reopened), 1 needs negative pin. LLVM multi-file infrastructure present (15 unit tests, zero integration tests). Extension parser and basic evaluator ahead of roadmap. Constant parser ahead of roadmap. Verified 2026-03-29.

  • Core module imports working (relative, module, private, aliases)
  • Visibility system working (pub, private by default, ::) — note: pub on config vars parser-only, evaluator incomplete
  • Module resolution working (path resolution, stdlib lookup, directory modules, file precedence)
  • Cycle detection working (Rust unit tests: loading_context_cycle_* in oric/src/imports/tests.rs)
  • Test module private access working (_test/ convention, test_module_access.test.ori)
  • Built-in prelude types and functions working (Option, Result, Ordering, print, panic, etc.)
  • Auto-load stdlib prelude (use std.testing works across the 415 of 882 spec/library .ori files that import it)
  • Self type parsing in traits (see Section 3)
  • Trait/impl parsing at module level (see Section 3)
  • Module alias syntax (use "../path" as alias) — parsing/runtime complete
  • Re-exports (pub use) — basic parsing/resolution complete WEAK TESTS — self-test only, no cross-module consumption
  • Qualified access (module.function()) — runtime complete
  • Type checker ModuleNamespace support — pending
  • LLVM multi-file AOT compilation — infrastructure exists (multi_file.rs, 15 unit tests), no integration tests
  • Enhanced cycle error messages (4.4) — pending
  • Type definitions parsing (see Section 5)
  • Module system negative tests — zero #compile_fail tests exist for the module system
  • Cross-module type import test — pub type Point declared but never imported cross-module
  • Cross-module re-export consumption test — reexporter.ori tests itself but nobody imports from it
  • oric/src/imports/mod.rs file split — 603 lines, exceeds 500-line limit
  • Run full test suite: ./test-all.sh
  • /tpr-review passed — independent Codex review found no critical or major issues (or all findings triaged)
  • /impl-hygiene-review passed — implementation hygiene review clean (phase boundaries, SSOT, algorithmic DRY, naming). MUST run AFTER /tpr-review is clean.
  • /improve-tooling retrospective completed — MANDATORY at section close, after both reviews are clean. Reflect on the section’s debugging journey (which diagnostics/ scripts you ran, which command sequences you repeated, where you added ad-hoc dbg!/tracing calls, where output was hard to interpret) and identify any tool/log/diagnostic improvement that would have made this section materially easier OR that would help the next section touching this area. Implement every accepted improvement NOW (zero deferral) and commit each via SEPARATE /commit-push. The retrospective is mandatory even when nothing felt painful — that is exactly when blind spots accumulate. See .claude/skills/improve-tooling/SKILL.md “Retrospective Mode” for the full protocol.
  • /tpr-review passed — independent review found no critical or major issues (or all findings triaged)
  • Subsection close-out (4.10) — MANDATORY before starting the next subsection. Run /improve-tooling retrospectively on THIS subsection’s debugging journey (per .claude/skills/improve-tooling/SKILL.md “Per-Subsection Workflow”): which diagnostics/ scripts you ran, where you added dbg!/tracing calls, where output was hard to interpret, where test failures gave unhelpful messages, where you ran the same command sequence repeatedly. Forward-look: what tool/log/diagnostic would shorten the next regression in this code path by 10 minutes? Implement improvements NOW (zero deferral) and commit each via SEPARATE /commit-push using a valid conventional-commit type (build(diagnostics): ... — surfaced by section-4.10 retrospectivebuild/test/chore/ci/docs are valid; tools(...) is rejected by the lefthook commit-msg hook). Mandatory even when nothing felt painful. If genuinely no gaps, document briefly: “Retrospective 4.10: no tooling gaps”. Update this subsection’s status in section frontmatter to complete.
  • /sync-claude section-close doc sync — verify Claude artifacts across all section commits. Map changed crates to rules files, check CLAUDE.md, canon.md. Fix drift NOW.
  • Repo hygiene check — run diagnostics/repo-hygiene.sh --check and clean any detected temp files.