agent: builder model: opus max_turns: 110 budget_usd: 25 —

R0: the compiler’s Nikaia leaves std for crates/nikaia-compiler (#921)

Score terms (docs/priorities.md, docs/bootstrap.md section 1): owner’s correction 2026-10-28, point 3: the compiler’s Nikaia sits in crates/nikaia-std/src/tools and from outside reads as part of the standard library. One mechanical move commit, at a quiet moment; no line of logic changes, the self-hosted share stays where it is.

When this runs (the supervisor checks it before starting)

Facts

Target layout (decided)

crates/nikaia-compiler/          the compiler, in Nikaia (package `nikaia-compiler`, lib `nikaia_compiler`)
  Cargo.toml
  src/lib.rs                     the hand-written Rust of the old `mod tools`, as the crate root
  src/*.nika                     the 242 files (one package, ADR-294)
  src/described.contracts
  src/lowered.rs, src/lowered/   generated by `nikaia lower-std`
  tests/rust_signatures.rs       moved from crates/nikaia-std/tests
crates/nikaia/                   the `nikaia` binary: the thin Rust adapter beside it
crates/nikaia-std/               std only; no `compiler` feature, no `tools/`

Rust paths: nikaia_std::tools::X becomes nikaia_compiler::X (nikaia_std::tools::ty::Ty -> nikaia_compiler::ty::Ty).

To build (one commit at the end; nothing is pushed in between)

  1. Precondition. git fetch origin develop && git merge --ff-only origin/develop; git status --short crates scripts must be empty (other agents’ untracked files outside those, e.g. docs/briefs/*.report.md, are not yours: leave them). If not empty: stop, Status: blocked, list the files. df -h /home/user into the report.
  2. The sysroot path first, in the old place, with the old binary. In sysroot_cache.nika: replace SYSROOT_TOOLS by comptime SYSROOT_COMPILER_DIR: ref String = "nikaia-compiler" and make sysroot_tools_dir(root) return root.join(SYSROOT_COMPILER_DIR).join("src"); correct the doc comments of :24-28, :32, :67-78, :102 to say crates/nikaia-compiler/src. Run target/fast/nikaia lower-std (the old binary still reads and writes the old directory) so the committed lowered/sysroot_cache.rs carries the new path. Without this order the new binary would look for the package where it is not.
  3. Move with history. mkdir -p crates/nikaia-compiler/src crates/nikaia-compiler/tests; git mv crates/nikaia-std/src/tools/* crates/nikaia-compiler/src/ (.nika, described.contracts, lowered.rs, lowered/); git mv crates/nikaia-std/tests/rust_signatures.rs crates/nikaia-compiler/tests/. crates/nikaia-std/src/tools must be gone afterwards.
  4. The crate. crates/nikaia-compiler/Cargo.toml: name = "nikaia-compiler", edition = "2024", rust-version = "1.88" with the ADR-305 comment as in nikaia-std’s; dependencies: nikaia-std (workspace, no features), winnow-grammar and every other crate the build names as missing (copy the version from crates/nikaia-std/Cargo.toml; add none that the build does not ask for); dev-dependencies what rust_signatures needs. Root Cargo.toml: the member crates/nikaia-compiler and nikaia-compiler = { path = "crates/nikaia-compiler" } under [workspace.dependencies]. crates/nikaia/Cargo.toml:43: nikaia-std = { workspace = true } and nikaia-compiler = { workspace = true }; keep its comment, corrected.
  5. src/lib.rs. Cut lines 228-~619 of crates/nikaia-std/src/lib.rs (the allow block, the doc comment, pub mod tools { ... }) and paste them as crates/nikaia-compiler/src/lib.rs: the #[allow(...)] list becomes #![allow(...)] at the crate root, the mod tools { wrapper and its brace go, the doc comment becomes the //! crate comment (say: the compiler, in Nikaia; ADR-294 D21), include!("lowered.rs"), every crate::<std item> becomes nikaia_std::<std item>. Remove the compiler feature and its comment from crates/nikaia-std/Cargo.toml, and the rust_signatures [[test]] block (now the new crate’s; drop its required-features).
  6. Rust callers. In crates/nikaia/src, crates/nikaia/tests, crates/nikaia-compiler/src/lib.rs, crates/nikaia-compiler/tests: first use nikaia_std::tools; -> use nikaia_compiler as tools; (if any), then nikaia_std::tools:: -> nikaia_compiler::, then any remaining nikaia_std::tools -> nikaia_compiler. sed -i over git grep -l; not in lowered/ (regenerated in step 8).
  7. Paths in text and tools. crates/nikaia-std/src/tools -> crates/nikaia-compiler/src (and nikaia-std/src/tools -> nikaia-compiler/src, src/tools/ where it means this directory) in: crates/nikaia/src, crates/nikaia/tests, crates/nikaia-compiler/src/*.nika (comments; nikaia_std::tools::m in the head comments -> nikaia_compiler::m), crates/rs2nika/convert (not its target/), scripts/self_hosting.py, scripts/where.nika, scripts/tokenspeed.nika, scripts/test_bump.sh, .github/ (if any), .claude/agents/builder.md, docs/builder-facts.md, docs/selfhosting-plan.md, docs/modular-compiler.md, examples/README.md. Not in docs/bootstrap.md (it names both places on purpose), docs/history/, docs/briefs/ (records), CHANGELOG.md, or ADRs other than ADR-294. CLAUDE.md’s clippy sentence becomes: “Lints about code the lowering writes are allowed at the crate root of crates/nikaia-compiler (src/lib.rs), not fixed in the generated files (crates/nikaia-compiler/src/lowered/*.rs, index lowered.rs; a change to one .nika changes one file).” In scripts/self_hosting.py also count crates/nikaia-compiler/src/lib.rs as hand-written Rust of the toolchain (it was outside the count inside std); say the new total in the report.
  8. Build and fixpoint. cargo build --profile fast -p nikaia; fix what it names (a pub(crate) std item the package reaches becomes pub with #[doc(hidden)]; list each in the report). Then cold: NIKAIA_CACHE_DIR=$(mktemp -d) target/fast/nikaia lower-std. Expected: the generated files differ from step 3’s only where a .nika comment changed in step 7 (doc comments are carried into the Rust). Build again, run lower-std again: no diff (the fixpoint). cargo build -p nikaia-std alone must build too (a program’s std, without the compiler).
  9. Specification (text decided by the architect; the version raise is the supervisor’s, do not touch version lines, CHANGELOG.md, badges other than self-hosted.svg):
    • docs/specification/adr/adr-294.md: in D18 the path becomes crates/nikaia-compiler/src/lowered/<stem>.rs and src/described.contracts; in D19 tools::ty, tools::ledger, tools::rust become nikaia_compiler::ty, …, nikaia_std::tools::ty::Ty becomes nikaia_compiler::ty::Ty, “The Rust that nikaia-std writes beside the package” becomes “The Rust written by hand beside the package (crates/nikaia-compiler/src/lib.rs)”. After D20 add:

      D21 — The toolchain’s Nikaia is a crate of its own, not part of std.

      (2026-10-28, owner.) The package of D18 lives in crates/nikaia-compiler/src and is compiled as the crate nikaia-compiler, which depends on nikaia-std as any Rust caller does; crates/nikaia, the nikaia binary and the Rust adapter around the package, depends on both. It stood in crates/nikaia-std/src/tools behind std’s compiler feature (#723), and from outside it read as part of the standard library or as a helper tool. The feature is gone: a program’s std is that crate as it always was. What the package may read of std is unchanged: what std.contracts publishes, and its own described.contracts (D9.3). std’s unpublished run-time Nikaia (crates/nikaia-std/src/runtime, #723) stays in std: a program runs it.

    • docs/specification/30-nikaia-tooling.md:56: replace “the toolchain’s own Nikaia, src/tools, is one package lowered into one package.rs (ADR-294 D18)” by “the toolchain’s own Nikaia is not part of std: it is the crate nikaia-compiler, one package lowered into one lowered.rs (ADR-294 D18, D21)”.

  10. Gate. cargo fmt; cargo clippy --all-targets -- -D warnings beside the last test run; the whole it binary once, no filter (cargo test --profile fast -p nikaia --test it: 15 test files changed paths, and the_committed_rust_is_what_this_compiler_lowers is the fixpoint); cargo test --profile fast -p nikaia-compiler; the guard tests (range_spelling, shipped_ledger, the std ledger in contracts); nikaia run scripts/where.nika -- sysroot_tools_dir (finds it at the new path); bash scripts/test_bump.sh if it is in the gate (it names the old path); python3 scripts/badges.py; scripts/pre-push-check.sh. Not tests/compiler --both-settings: no check_*/emit_* logic changed.
  11. One commit, files added by name or by the directories this brief owns (git add crates/nikaia-compiler crates/nikaia-std crates/nikaia crates/rs2nika/convert/src Cargo.toml Cargo.lock scripts .claude/agents/builder.md CLAUDE.md docs/builder-facts.md docs/selfhosting-plan.md docs/modular-compiler.md examples/README.md docs/specification assets/badges/self-hosted.svg; check git status first that nothing of another agent is among them). Message: Move the compiler's Nikaia out of std into crates/nikaia-compiler (ADR-294 D21), body: the layout above in three lines, Fixes #921. git push origin develop (fast-forward; rejected: report it, do not rebase).

Rules

Report (at most 15 lines)

Status: done | blocked | partial
Commit: <sha> (pushed | rejected)
Paths changed: <count> files, <renames> renames
Made pub: <std items, or none>
Self-hosting: <Nikaia lines> / <share> (before 87,5xx / 80.7 %)
Fixpoint: lower-std twice, no diff: yes | no
Tests: it <pass/fail>, nikaia-compiler <pass/fail>, guards, clippy, pre-push
Disk: <GB free before> -> <after>
Deviation: <none | what and why>
Found: <none | compiler defect, with probe>
Changelog: one line for the supervisor's raise (ADR-294 D21, Part III)
Owner: <none | question>
This site is open source. Improve this page.