Skip to content

Toolchain manifests ​

A Toki worker can provision the exact tools a project needs and fingerprint them, so that a result names precisely what built it. A project declares those tools in a per-platform toki-toolchains-<os>-<arch>.toml file, together with the standard rust-toolchain.toml.

File names ​

The worker looks for its native file first, then a generic fallback:

  1. toki-toolchains-<os>-<arch>.toml
  2. toki-toolchains.toml
osarch
windowsx86_64, aarch64
macosx86_64, aarch64
linuxx86_64 only (native GNU/glibc on Ubuntu 24.04 LTS)

Platform-specific files let one project pin different native executables per platform without changing its source. The Toki repository itself carries one file per platform:

text
toki-toolchains-linux-x86_64.toml
toki-toolchains-macos-aarch64.toml
toki-toolchains-macos-x86_64.toml
toki-toolchains-windows-aarch64.toml
toki-toolchains-windows-x86_64.toml

Minimal manifest ​

A Rust-only project needs only the schema and its native platform:

toml
schema = 1
os = "macos"
arch = "aarch64"

schema must be 1, and os and arch must name the worker's own platform. Unknown keys are refused.

Rust: rust-toolchain.toml ​

When rust-toolchain.toml is present, the worker installs its exact Rust release and requested components through an existing rustup installation, without changing the default toolchain.

toml
[toolchain]
channel = "1.99.1"
components = ["rustfmt", "clippy"]
profile = "minimal"
  • channel must be an exact numeric release (major.minor.patch). Floating channels such as stable and path toolchains fail setup.
  • profile may be minimal or default.
  • Cross-compilation targets fail setup; only native releases are supported.

The report records the actual rustc and cargo digests, every file in the installed bin directory, release and host probes, and the component list. Installed component payloads, including compiler libraries and native rust-std libraries, are validated and fingerprinted.

Other tools: [[tools]] ​

Node, package managers, nextest and other helpers are pinned with [[tools]] entries:

toml
schema = 1
os = "linux"
arch = "x86_64"

[[tools]]
name = "node"
executable = "tools/node/bin/node"
digest = "<64 hex digits>"
version_args = ["--version"]
version = "v22.11.0"

[tools.install]
program = "scripts/install-node"
args = ["22.11.0"]
KeyMeaning
nameUnique name: ASCII letters, digits, -, _ or ..
executablePath to the executable. Relative paths resolve from the project.
digestToki's content digest of the executable's bytes, as 64 hex digits.
version_argsArguments for the version probe. Must not be empty.
versionThe exact expected probe output: stdout then stderr, outer whitespace removed.
installOptional. program and args to run from the project when the tool is missing.

The install command runs only when the tool is missing, with no shell interpretation. Success still requires the exact digest and version. Existing drift is never silently repaired.

Computing a tool digest

Toki's content digest is BLAKE3 in key-derivation mode with the context string toki 2026-10 content digest, written as lowercase hex.

Native SDKs and system tools ​

Toki measures system tools but never installs them. Installing them stays host administration.

Windows. Workers start in their native MSVC developer environment (VCToolsInstallDir, VCToolsVersion, WindowsSdkDir, WindowsSDKVersion, INCLUDE, LIB, LIBPATH, PATH). Setup measures cl and link, their compiler binaries and DLLs, MSVC headers and runtime libraries, all headers of the selected SDK and its import libraries for the native architecture.

macOS. Setup measures the selected developer tools, C/C++ compiler, linker and the complete selected SDK.

Linux. Administrators supply GCC/G++, binutils and glibc development files; Toki never runs a package manager or privileged installer. Setup measures /etc/os-release, the kernel, glibc, compiler and linker bytes, GCC payloads, system headers, startup objects and runtime libraries. Rust targets x86_64-unknown-linux-gnu. Other distributions, musl, other architectures, non-system sysroots and tool selection overrides fail setup.

Missing tools, components or SDK files fail setup.

How a worker uses the manifests ​

  1. The operator sets builds.toolchainRoot in the worker configuration to an absolute directory holding the manifests.
  2. Before registering, the worker provisions that inventory and measures it. Failure prevents registration.
  3. The worker advertises the measured digest as its toolchainIdentity.
  4. A client submits with command.toolchainIdentity set to that digest and a requiredPlatform. Only workers whose identity and platform match are selected.
  5. Before and after each command, the worker re-checks the manifest, versions, executables and SDK identity. Drift fails the attempt as a setup failure, with no exit verdict or receipt.
  6. The receipt's toolchain digest is the requested, measured identity.

The worker runs commands with absolute paths to the pinned tools and the measured environment. On Linux, PATH lists the pinned Rust bin directory followed by /usr/bin.

After an intentional tool update, restart the worker so it provisions and registers again. A configuration reload cannot change the inventory.

What a toolchain identity is not

The identity is observational evidence under the worker's credential, not hardware attestation. It covers tool selection only. It grants no hermeticity for other inputs, and it includes the worker's identity, so results are never reused across workers even when hosts look identical.

Without a manifest ​

Requests without toolchainIdentity keep the older record-only behaviour: their receipts are scoped to the worker and claim no provisioned toolchain. A worker that has a toolchainRoot still selects and verifies its pinned tools for those commands; a worker without one runs them with the tools it has.

Part of the Tama toolchain.