Result: done
Files: crates/nikaia-std/src/tools/sysroot_cache.nika crates/nikaia-std/src/tools/lowered/sysroot_cache.rs crates/nikaia-std/src/tools/lowered.rs crates/nikaia/src/sysroot.rs crates/rs2nika/convert/rs2nika.names scripts/self_hosting.py docs/selfhosting-plan.md assets/badges/self-hosted.svg crates/nikaia-std/src/lib.rs
Commit: sysroot: paths, package and cache keys into Nikaia (S2)
Body: New tools/sysroot_cache.nika: the sysroot’s paths (std_dir, tools_dir, runtime_dir, std_modules, tool_modules, nika_in, which also serves tools_sources), cpu_levels and the parse of native’s key, the Package operations (committed, inlined, contains, drift, stale, pack, unpack) over the Rust struct’s Vec[(String, String)], and lower-std’s cache: the module key, get, put, the package interface and the file key. Package and LoweredBefore stay Rust structs (Display, the Rust tests build them) and delegate; the fs reads and writes are async in std, so sysroot.rs calls those through rt::exec::block_on, as describe.rs calls sources.nika. What std cannot say is the SysrootHost trait, implemented by sysroot.rs’s Host: sha256hex, use_entry, unique_beside, rustc_cpus (user_cache_dir was not needed: LoweredBefore’s root stays Rust). The keys are byte for byte the old ones: the Debug texts are made in Rust and passed in, part/length/ended are module fns; checked with a temporary unit test computing the old Rust bytes beside the new (module key, interface, file key, get/put, pack/unpack, inlined, native parse), not committed. 221 Rust lines gone; self-hosting share 80.2 %. Fixes met on the way, committed first: 337e7023 (emit: ?. on a file’s name), 198ded41 (tools import seq::Join). lib.rs allows three more clippy lints on the lowered tools (precedence, manual_unwrap_or_default, needless_borrows_for_generic_args), as CLAUDE.md says for generated code.
Part: #125
Pushed: 9826a9ef5217d06b84f2f8e0015c0a7610a88708
Tests: nikaia test –both-settings –project tests/compiler ok (205); cargo test -p nikaia –lib sysroot:: ok (9); it – sysroot lower_std native cpu package drift ok (86); lower-std fixpoint: after the build 0 of 240 (new compiler), then unchanged; per-file reuse shown by the_per_file_cache_follows_the_interface (2 of 2, 1 of 2); self-hosting 80.2 %; probe commit 070b9c7c; guard set ok (22); pre-push ok; clippy clean
Gate: green
Deviation: none
Found: the checker accepts a ref String loop element moved into a tuple literal (for name in names { files.push((name, 1)) }, names a Vec[String] built at run time): rustc E0308, where the same move into push or a struct field is refused (NK1102, NK1106)
Needs: none
Changelog: none
Owner: none
Disk freed: 0 GB (cache 4.0G, 16G free of 252G; new entry over 100 MB: run-bundle/65d964130cc06fb2 300 MB)
Rs2nika: kept 16 of 170 lines; costliest: the draft wrote methods of Sysroot/Package/LoweredBefore, which stay Rust, and PathBuf/Path (now free sysroot fns over fs::Path, names table extended); the part closure over a mut Vec[u8] with to_le_bytes/extend_from_slice (module fns sysroot_part/length/ended); std::fs calls, ? chains, split_inclusive, last_mut()?, then_some rewritten to fs:: with Root::Anywhere, catch and ?? return