Today — prepare_scratch (crates/launchbound-build/src/scratch.rs:31-38) builds the scratch crate from Cargo.toml, Cargo.lock, and the entries of src/ that are files — if entry.path().is_file() { copy }. A subdirectory of src/ is skipped without a word. Measured against 2.0.0 with the corpus reduce-flip kernel, unchanged except that one constant moved into a module directory:
$ find src -type f
src/lib.rs
src/params.rs
src/util/mod.rs
$ sed -n '5,6p' src/lib.rs
mod params;
mod util;
$ cargo check # the crate itself is fine
Finished `dev` profile
$ launchbound prune ./reduce-flip --cc 8.6 --reconverge-dir <reconverge 0.4.0 bin dir>; echo exit=$?
reduce-flip (cc 8.6):
! c1-9b9fe33407467e5e block_x=32 tile=128
TOOL ERROR (hard stop): cargo reconverge exited 2:
error: could not compile `reduce-flip` (lib) due to 1 previous error
error: `cargo check` under the reconverge driver failed (see the errors above). If rustc reported real build errors, fix those and rerun; if the driver itself failed to start (for example `error while loading shared libraries`), the toolchain does not match the driver — run `cargo reconverge setup` to install nightly-2026-04-03 and the matching binaries
… the same for all eleven …
=> 0 clean, 0 with caveats, 0 refused, 11 tool errors
exit=2
$ find target/launchbound-scratch/reduce-flip -type f
target/launchbound-scratch/reduce-flip/Cargo.toml
target/launchbound-scratch/reduce-flip/Cargo.lock
target/launchbound-scratch/reduce-flip/src/lib.rs
target/launchbound-scratch/reduce-flip/src/params.rs # no src/util/
$ cd target/launchbound-scratch/reduce-flip && cargo check 2>&1 | grep '^error'
error[E0583]: file not found for module `util`
error: could not compile `reduce-flip` (lib) due to 1 previous error
Control — the same kernel with the constant back in lib.rs, same command: => 3 clean, 0 with caveats, 8 refused, 0 tool errors, exit 0.
Why it is worth fixing — mod util; with src/util/mod.rs is how Rust code is organised past one file. The six corpus kernels are single-file because corpus/README.md asks them to be ("keep this minimal and readable, it is a fixture"); a kernel crate someone actually tunes has a kernels/ or util/ directory more often than not. Every such crate hard-stops with a message that tells its author to fix build errors the crate does not have, or to reinstall the toolchain — and the gate never says "the copy I compiled was not your crate". The scratch mechanism is documented as a property ("the repo copy is never touched") and nowhere as a boundary, so there is nothing to find.
Not measured here, and worth checking in the same pass: a build.rs at the crate root is not copied either, and neither is anything Cargo.toml's [lib] path or [[bin]] points at outside src/.
Fix — copy src/ recursively, and copy build.rs (or whatever package.build names) beside Cargo.toml; skip target/. A few lines with a directory walk. Orthogonally, and cheap: when the scratch compile fails, have the tool-error detail name the scratch path, so the next person can cd there and see what was actually compiled.
Done when — a kernel whose src/ has a subdirectory gets the same verdicts from the gate that cargo check gives the crate; a test in launchbound-build runs prepare_scratch over a crate with src/a/mod.rs and asserts the file is in the scratch; a scratch compile failure's detail names the scratch directory.
Today —
prepare_scratch(crates/launchbound-build/src/scratch.rs:31-38) builds the scratch crate fromCargo.toml,Cargo.lock, and the entries ofsrc/that are files —if entry.path().is_file() { copy }. A subdirectory ofsrc/is skipped without a word. Measured against 2.0.0 with the corpusreduce-flipkernel, unchanged except that one constant moved into a module directory:Control — the same kernel with the constant back in
lib.rs, same command:=> 3 clean, 0 with caveats, 8 refused, 0 tool errors, exit 0.Why it is worth fixing —
mod util;withsrc/util/mod.rsis how Rust code is organised past one file. The six corpus kernels are single-file becausecorpus/README.mdasks them to be ("keep this minimal and readable, it is a fixture"); a kernel crate someone actually tunes has akernels/orutil/directory more often than not. Every such crate hard-stops with a message that tells its author to fix build errors the crate does not have, or to reinstall the toolchain — and the gate never says "the copy I compiled was not your crate". The scratch mechanism is documented as a property ("the repo copy is never touched") and nowhere as a boundary, so there is nothing to find.Not measured here, and worth checking in the same pass: a
build.rsat the crate root is not copied either, and neither is anything Cargo.toml's[lib] pathor[[bin]]points at outsidesrc/.Fix — copy
src/recursively, and copybuild.rs(or whateverpackage.buildnames) besideCargo.toml; skiptarget/. A few lines with a directory walk. Orthogonally, and cheap: when the scratch compile fails, have the tool-error detail name the scratch path, so the next person cancdthere and see what was actually compiled.Done when — a kernel whose
src/has a subdirectory gets the same verdicts from the gate thatcargo checkgives the crate; a test inlaunchbound-buildrunsprepare_scratchover a crate withsrc/a/mod.rsand asserts the file is in the scratch; a scratch compile failure's detail names the scratch directory.