Concepts
This page introduces the vocabulary used across Toki. Each section is short and links to a deeper page where one exists.
Requests, actions and attempts
Toki keeps separate identities for things that are easy to conflate:
- a request is one logical ask from a client (
req-…), made idempotent by its key; - an action is the work that request asks for;
- an attempt is one physical run of that action on one worker;
- a lease grants one attempt the right to run and publish;
- a receipt is the published result of the attempt that produced it.
Every published observation names exactly one attempt, so retries never mix their logs or costs.
Actions and action keys
An action key is the logical identity of an action's result: a versioned digest over everything that can change that result. Its components are the declared input digests, the operation, the working directory, the exact digest of every tool, the target, the flags, the allow-listed environment, upstream artefacts and the platform. The derivation version is part of the encoding, so changing it changes every key.
A key alone does not allow reuse. Each kind of action has a hermeticity class:
- Hermetic: every external input is absent, keyed or neutralised. The result may be reused, and identical in-flight runs may share one execution.
- Non-hermetic: some input (build-script reads, environment, native libraries, SDKs, network, clocks, Git state) is not proven covered. Runs are recorded but never reused or shared.
Today's whole-command Cargo and Node adapters make no hermeticity claim, so their results are record-only. Cargo's own freshness never authorises reusing a test result.
Placement
A request can name the platform its result must hold for. Placement matches three dimensions:
- OS, for example
windows,macosorlinux; - architecture, for example
x86_64oraarch64; - toolchain digest, the measured identity of the worker's provisioned tools.
The executor refuses when no registered worker matches all three. The binding is made on first dispatch, stored durably and kept across retries.
On the network build path, a client sets requiredPlatform: { os, arch }. If no compatible worker is connected, the build ends as refused with the code required_platform_unavailable. See Builds.
Workers and the registry
A worker runs commands. Network workers dial the coordinator over authenticated TLS and advertise what they can do: OS, architecture, labels, toolchain identity and optional capabilities such as artefact collection or Gin snapshot providers. A client selects a worker by its authenticated subject, or by a label as class:<label>.
Each worker runs one command at a time. See Workers.
Leases and fencing
Every start grants a distinct lease and a fencing epoch before dispatch. Workers renew the lease while they run. Expiry is exclusive: at the deadline, the lease is already lost.
Beginning, ending, observations and receipts all check current ownership and the store's own clock inside their write transaction. A worker's timestamp cannot restore ownership. When a newer epoch takes over, late reports from the older attempt are fenced out.
The practical effect:
- a lost connection or coordinator restart does not run a command twice;
- an attempt whose outcome is unknown is reported as indeterminate, never as a success;
- once the worker reconnects, its journal can confirm the outcome, which is then published once.
CAS and manifests
The worker-local artefact store is a content-addressed store (CAS). Blobs are addressed by Toki's content digest. A manifest binds an action key to named output digests and their executable bits.
Every read, materialisation and upload verifies a private snapshot of the bytes. A mismatch drains the store and its workers and leaves a marker that refuses work until an operator inspects it. This detects tampering by same-user actions; it is not isolation from a hostile account. Manifests record provenance; they do not grant result reuse on their own.
See Builds.
Receipts
A receipt is published, with its outbox entry and payload, in one fenced transaction. Its payload, toki.execution, is versioned on its own: a minor version only adds optional fields, so readers accept every minor of their major and ignore unknown fields.
The payload includes the source identity, the platform the result holds for, declared and observed inputs (secret-looking names are redacted, other values are digests), every attempt, test evidence, and links to retained logs, artefacts and the containment report.
Test evidence is strict. A zero-test selection never passes, and incomplete evidence makes the verdict incomplete, even when the command exited 0.
An accepted request that carries a selection manifest but ends without a result (refused, cancelled, expired or failed) exports a separate terminal payload (toki.terminal) instead. It has no verdict and cannot be read as a result.
Source providers
Toki names source state with provider-qualified, versioned identities:
| Provider | Identity | What it names |
|---|---|---|
| Git | git/v1:<digest> | a committed tree read from a local repository or mirror |
| Gin snapshot | gin-snapshot/v2:<digest> | a published Gin snapshot's canonical root |
| Gin snapshot (legacy) | gin-snapshot/v1:<digest> | an older encoding, still readable in historical evidence |
A Git identity depends on the tree, not the commit: two commits with the same tree share an identity. Toki never compares digests across providers, and a Git object name is never read as a source identity.
For Git, the commit must be a complete object name; abbreviations, refs and tags are refused. Gin snapshots are placed by the separately installed gin executable through its versioned view contract. See Builds.
Checkouts
Line endings, symbolic links, long paths and case handling depend on Git configuration. On Windows, macOS and Linux, a worker checks committed source out under a pinned reference configuration (git-checkout/v1) that ignores system, global and user Git settings, and records it in the receipt. See Builds.
Toolchains
A worker can provision its tools from a project's toki-toolchains-<os>-<arch>.toml and rust-toolchain.toml. It installs the exact Rust release through rustup, measures executables, SDKs and system libraries, and advertises the result as its toolchain identity. Drift is detected before and after each command. See Toolchains.
Containment and accounting
Each command runs inside a native process boundary:
| Platform | Boundary | Limits |
|---|---|---|
| Windows | Job Object | CPU rate and committed-memory threshold |
| Linux | cgroup v2, when a delegated subtree is configured; otherwise process group | CPU quota, memory ceiling, task count |
| macOS | best-effort descendant tracking | none; limits are refused |
Each result reports the boundary actually established, the limits enforced, how the command ended and its resource accounting (wall time, CPU, memory, I/O), with the scope and completeness of each measurement. Values a platform cannot measure stay unavailable, never zero. See Workers.
Test history
Toki owns the history of the tests it runs and is designed to ingest CI results too. The model (test identities, per-attempt timings and machine descriptors) exists; storage, flakiness detection and queries are planned. See Test history.