Result: done
Files: crates/nikaia-std/src/tools/project_tests.nika crates/nikaia-std/src/tools/lowered/project_tests.rs crates/nikaia-std/src/tools/lowered.rs crates/nikaia-std/src/lib.rs crates/nikaia/src/project.rs docs/selfhosting-plan.md assets/badges/self-hosted.svg
Commit: project: the test runner’s run loop into Nikaia (P3b)
Body: The cut: the loop of run_tests over tests and settings stays Rust (with Sandbox, outcome_of, the compiler’s own build/run in run_program_test, and the failures’ report, whose block-test stdout is printed through from_utf8_lossy, which std has no counterpart for; moving the loop whole would also need a throwing callback, of which tools/*.nika has none yet), and Nikaia does each test’s work: project_tests_output_outcome (reads the .out/ files from the sandbox and decides passed), project_tests_refused_outcome and project_tests_ran_outcome (run_program_test’s two outcomes), ProjectTestsBlessed with project_tests_bless and project_tests_bless_program (decision and write), project_tests_blessed_line, project_tests_explain_output, the labels, the “running N tests” and “test result” lines and the exit code. The moved Rust (bless, bless_program, Blessed, explain_output and the outcome blocks) is deleted; every printed line is the same. A write that fails while blessing now fails with std’s IoError text (it names the path) instead of anyhow’s “blessing PATH”, as P3a did for reads. clippy::manual_ok_err is allowed on the tools module (the lowering writes match fs::read(..) { Ok(v) => Some(v), Err(_) => None } for catch { null }). No .clone() for #909 was needed.
Part: #125
Pushed: 5681395a94e1574f2f15837dcc6afd78ef3a897f
Tests: nikaia test –both-settings –project tests/compiler 206 passed (as before); it filtered output_test program_test bless test_runner refusal + guard set 52 passed; cargo test -p nikaia –lib project:: 10 passed; –bless probe on a scratch package (an output test and a test program with wrong .stdout): both lines blessed, both files rewritten, the next run ok; lower-std fixpoint (second run unchanged); clippy clean; pre-push-check clean; self-hosting 80.6 %
Gate: green
Deviation: none
Found: three lowering defects, met while writing the move, not in the committed code. (1) a ref Bytes? parameter lowers to Option<&[u8]> but its argument is opened with .as_ref() (Option<&Bytes>), E0308; emit_arg_opening_inside in emit_core_args.nika names only String/str for .as_deref(). (2) want?.clone() of such a parameter lowers to .to_owned() (a Vec