Issue #538: A directory of a project is a package and a mod of one crate: use a::b, cycles allowed, [directories] (ADR-286 D37-D40)

Open and answer this issue on GitHub.

language, ready · opened 2026-10-07 · updated 2026-10-09 · 1 comment

Records: Part I 9.1 (a package is a directory), 9.2 (visibility is per package), the roadmap’s walls you will hit.

Where it stands. Modules are one level: a .nika file beside main.nika. src/a/b.nika is not found. The roadmap lists it as a wall, and nothing in the specification says what a subdirectory is, so this is a decision before it is work. Any project past a few files (and the toolchain’s own Nikaia, which is one package today, ADR-294 D18) runs into it.

The two readings

  src/a/ is a package of its own src/a/ is more files of the same package
follows from 9.1 yes: a package is a directory no: a package would be a tree
a name from it is written with its prefix, a::Row, as every other package’s bare, as now
pub is the boundary between a and the rest changes nothing
what it buys the structure is visible at every use; a directory is a unit of privacy only file organisation

The first reading looks like the one the rest of Chapter 9 already implies. It needs three answers:

Cost to weigh: today a package is one crate in the generated workspace (ADR-002, ADR-053). A package per directory multiplies crates and so rustc invocations, so measure a ten-directory project before deciding.

Comments

keywan-ghadami, 2026-10-09

Decided (owner, 2026-10-09)

How it was reached. The issue offered two readings: a subdirectory is a package of its own, or more files of the same package. The owner chose the first, lowered as mod. The trigger was a special treatment in the tests that this removes:

A mod per package is also how the build-time program already writes a dependency (pub mod <package>, ADR-321 D13, 0.0.590).

Refined in the same round:

Checked (0.0.710): src/model/row.nika with use model in main.nika is refused with there’s no dependency called model and a suggested [dependencies] path entry.

Where it is written: ADR-286 D37-D40 (D19 now covers dependencies only), Part I 9.1 and Part III 13.3, 0.0.711.

To build

  1. Discovery and naming. Read every directory under src/ that holds .nika (and that [directories] does not mark) as a package named by its path. use a::b resolves to it. A name that is both a dependency and a project directory is refused. Tests:
    • src/model/row.nika with use model and model::Row builds;
    • src/model/rows/ is reached as use model::rows and rows::Row;
    • a project directory and a [dependencies] key with one name are refused.
  2. One crate. Emit the project’s packages as nested mods of the project’s crate, each against its own ledger entries, pub per D2. Tests:
    • two packages that both declare Row build;
    • a private item of model is NK1110 from http;
    • the generated workspace has one member for the project.
  3. Cycles.
    • Tests: http and model using each other build and run.
    • The ledger of packages in a cycle is inferred together.
    • A cycle through a crate directory is refused in Nikaia’s words.
  4. [directories]. Tests per kind:
    • ignore (a .nika there is not read);
    • resources (published, read by asset);
    • tests (built under nikaia test only);
    • crate (its own crate; one with Rust beside its Nikaia builds).
  5. tests/language. One directory per topic, the file-name prefixes removed. Check whether tests/build-time can then join it (#468); if not, say why here.

Generated by Claude Code

Back to Open Issues