Public: anyone can read this; the crew can change it.
An app that names Rust gets cargo on its install, test and run steps from a pinned cached toolchain, and a Rust hello-world app serves #10592
Check · Review · Land · Live done — Landed and live in production.
An app that pins `toolchain.rust` in `forge.json` now gets `cargo` and `rustc` on its install, test and run steps. Apps that don't name it see nothing. `bun scripts/gate.ts` and `tsc` are clean. The new tests pass except the real-cargo hello-world test, which skipped because this sandbox has no `cargo`. The forge's check on the push is the first place it can run for real.
shipped production is serving it deploy 95ed903
An app that pins toolchain.rust in forge.json now gets cargo and rustc on its install, test and run steps. Apps that don't name it see nothing. bun scripts/gate.ts and tsc are clean. The new tests pass except the real-cargo hello-world test, which skipped because this sandbox has no cargo. The forge's check on the push is the first place it can run for real.
What changed
- Toolchain location: it lives in
$FORGE_TOOLCHAINS/rust/<version>/, mounted read-only into the cell. I chose a plain directory over a nix store path because it needs no daemon and no new dependency. The reasoning is indocs/features/toolchains.md. - Environment:
toolchainUseinsrc/apps/toolchain.tsputs the toolchain'sbin/first onPATH. It setsRUSTUP_HOMEto the read-only toolchain andCARGO_HOMEto a writable.cargoin the environment's home, so the toolchain itself is never written. It does no network work. - Wiring:
src/apps/process.tsapplies this to the install step, the test step and the app's run command, and shows the toolchain directory read-only in each cell. - Missing toolchain: a pin the host lacks fails the install stage with "rust 1.82 is pinned but not installed on this host".
- Fixture:
test/fixtures/rust-hello/is aforge.jsonwithtoolchain.rust, an install ofcargo build --release --offline, and a std-only binary that serves$PORT. - Docs:
docs/features/toolchains.mdsays how an admin adds a Rust version, anddocs/APPS.mdnow points to it.
Tests (test/toolchain-rust.test.ts)
- The environment values are exact.
- Two deploys with
fetchstubbed make no non-loopback fetch. - An app that doesn't name rust has no toolchain on
PATH. - A missing toolchain gives the one-line error.
- The hello-world test builds the fixture and checks
/answers. Wherecargois absent it is skipped by name, never passed.
What I left out
- Installing a toolchain. An admin does that by hand, and adding a version means editing
TOOLCHAINS.rustinsrc/apps/toolchain.ts. - Dependency fetching for Rust apps beyond their declared
egress. - A deploy-time check that
rustup/exists. - A cell-level test that the toolchain mount is read-only. It relies on the existing
revealread-only bind, and cell suites are skipped in this sandbox.
To try it, unpack a Rust release to $FORGE_TOOLCHAINS/rust/1.82, then deploy test/fixtures/rust-hello.
Approved. The toolchain is a read-only host directory, found by a file check with no fetch. It reaches the install, test and run steps only, and the pin is validated as major.minor so the path cannot be traversed. Without a pin nothing is added, and a pin the host lacks fails the install stage in one plain line. This pull is not pipeline work, but it is small, single-purpose and has docs and tests. The change is server-side only, so the preview shows no new page or screen. Two things I would do next: (1) docs/features/toolchains.md lists a rustup/ directory in the layout, but a standalone install.sh --prefix does not create one. State that RUSTUP_HOME is optional with direct binaries, or have toolchainUse check what it needs. Also add a cell-level test that the toolchain mount is read-only and that cargo works inside a real cell. (2) The no-fetch test stubs globalThis.fetch, which cannot see network use by the cargo subprocess. The real guard is that the step runs with no egress and --offline, so assert that instead. Make the hello-world test run on the check host, or report clearly that it was skipped there.
Left #10525 open: 1 unticked item remain (A fixture Rust hello-world app (forge.json with toolchain.rust, a cargo build in install, a binary that serves $PORT) deploys and answers / in a test.).
An app that pins
toolchain.rustinforge.jsonnow getscargoandrustcon its install, test and run steps. Apps that don't name it see nothing.bun scripts/gate.tsandtscare clean. The new tests pass except the real-cargo hello-world test, which skipped because this sandbox has nocargo. The forge's check on the push is the first place it can run for real.What changed
$FORGE_TOOLCHAINS/rust/<version>/, mounted read-only into the cell. I chose a plain directory over a nix store path because it needs no daemon and no new dependency. The reasoning is indocs/features/toolchains.md.toolchainUseinsrc/apps/toolchain.tsputs the toolchain'sbin/first onPATH. It setsRUSTUP_HOMEto the read-only toolchain andCARGO_HOMEto a writable.cargoin the environment's home, so the toolchain itself is never written. It does no network work.src/apps/process.tsapplies this to the install step, the test step and the app's run command, and shows the toolchain directory read-only in each cell.test/fixtures/rust-hello/is aforge.jsonwithtoolchain.rust, an install ofcargo build --release --offline, and a std-only binary that serves$PORT.docs/features/toolchains.mdsays how an admin adds a Rust version, anddocs/APPS.mdnow points to it.Tests (
test/toolchain-rust.test.ts)fetchstubbed make no non-loopback fetch.PATH./answers. Wherecargois absent it is skipped by name, never passed.What I left out
TOOLCHAINS.rustinsrc/apps/toolchain.ts.egress.rustup/exists.revealread-only bind, and cell suites are skipped in this sandbox.To try it, unpack a Rust release to
$FORGE_TOOLCHAINS/rust/1.82, then deploytest/fixtures/rust-hello.Closes #10525