> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://rivet.chrisboulton.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://rivet.chrisboulton.com/_mcp/server.

# Testing and local docs

> Validate the Rust implementation and preview the Fern site without publishing.

## Rust checks

For tests authored by manifest/module users, see [manifest and module tests](/guides/testing). Run all shipped scenarios, including child module suites, with `cargo run --bin rivet -- test examples/testing --recursive`. To run only the module's suite, use `cargo run --bin rivet -- test examples/testing/modules/config`.

```sh
cargo test --workspace --locked
cargo clippy --workspace --all-targets --locked -- -D warnings
cargo fmt --all --check
cargo check -p rivet-resources --no-default-features --locked
cargo check -p rivet-resources --features runtime --locked
```

Compiler/catalog contracts cover all function families, templates/heredocs/scoping/limits, YAML/JSON equivalence, hierarchy merges/removals/explanations, SOPS process safety and sticky sensitivity, static language, provenance, sensitivity, assets, graph validation, strict bundle receipt, and resource policies. Engine contracts cover deterministic convergence, noop behavior, intent, refresh recovery, and independent continuation. Native Linux checks exercise actual filesystem/process safety. Extension checks prove discovery without generic core changes.

## Plugin checks

```sh
cargo test -p rivet-plugin -p rivet-process --locked
cargo build --bin rivet --bin rivet-plugin-example --locked
```

These contracts cover actual subprocess reuse, protected installation/checksum/descriptor rejection, typed function results and annotations, lazy exports, verified assets, noop/idempotence, lost apply replies, pinned recovery, service property rejection, shared actions, notification coalescing, ownership conflicts, malformed/oversized frames, deadlines, and process-group cleanup.

The disposable Linux host suite runs `tests/host/plugin_workflow.py` through the public CLI. Its real-OpenSSH workflow checks target-local plugin approval, refusal before mutation when an installation is missing, and remote apply/idempotence. The example service is a file-backed protocol model rather than an OS daemon provider; native systemd remains covered by the service/exec host workflow.

## Disposable Linux workflow

With a Docker engine running, execute from the repository:

```sh
python3 tests/docker/run_tests.py         # Checks and host workflows
python3 tests/docker/run_tests.py checks  # Tests, lint, formatting, extensions
python3 tests/docker/run_tests.py host    # Build and exercise native convergence
python3 tests/docker/run_tests.py clean   # Remove this architecture's caches/image
```

The runner uses Ubuntu 24.04 with systemd as PID 1, native package/account tools, and Rust 1.93.0. It chooses ARM64 or x86_64 to match the host and retains named Cargo caches. Only the repository is mounted read-only; source is copied into the container. It uses a privileged container with a private cgroup namespace, intended for local conformance checks rather than untrusted-code isolation.

The host workflows in `tests/host/` cover files, modules/expansion, service/exec, accounts, packages, resource completion (file ownership/links/backups, timers, SSH authorization, and mounts), subprocess plugins, and SSH execution transport. They can also run as root on a disposable Ubuntu host with systemd. They create/delete actual objects; run them only in that disposable environment. `tests/docker/README.md` documents the runner in detail.

## SSH transport checks

```sh
cargo test -p rivet-transport --locked
cargo test -p rivet-cli --test target_cli_contract --locked
python3 tests/runner_release_packaging.py
```

Contracts cover actual-bundle compatibility, exact capability/schema tokens, malformed/oversized frames, chunked results, terminal-result/exit-status agreement, and CLI target selection. Packaging checks verify controller/runner digest pins and archives without publishing.

The Docker host suite's real-OpenSSH workflow exercises root/user caches, noninteractive sudo, compatible installed-runner reuse, corrupt transfer/cache rejection, strict host keys, noop/apply/idempotence, and interrupted-run recovery without replay.

To exercise a macOS controller against a separately built Linux runner of the Docker engine's native architecture:

```sh
cargo build --bin rivet --locked
python3 tests/docker/controller_ssh_workflow.py target/debug/rivet /path/to/rivet-linux-aarch64
```

This helper creates/removes its own disposable target, temporary keys, and verified known-hosts, and checks bootstrap, facts, controller compilation, plan/apply/idempotence, and journal inspection. It leaves the operator's SSH configuration unchanged. ARM64 runtime checks have passed; Linux x86_64 runtime validation, release-workflow execution, and published HTTPS artifact acquisition remain release gates.

## Distribution checks

```sh
cargo test -p rivet-distribution --locked
cargo test -p rivet-compiler --test trusted_facts_contract --locked
cargo test -p rivet-cli --locked

# Opt-in local small-file/cache workload; no production capacity claim.
cargo test -p rivet-distribution --test distribution_scale --locked -- --ignored --nocapture
```

Distribution contracts cover deterministic publication, incomplete releases, conditional promotion/rollback, deleted pointers, indexed acquisition, private cache safety, corruption, complete preparation, and offline reuse. CLI fixtures exercise S3/GCS preconditions, signed delivery/refresh, native HTTPS/mTLS, certificate expiry/revocation, generated RSA GCP/OIDC tokens, policy denial, forged inventory, and trusted claims. Compiler contracts check typed claims, missing trusted contexts, claim bounds, and digest stability across unused claims/credential rotation.

On a disposable Linux host, the standalone source-mode workflow exercises noop, convergence, idempotence, drift repair, promotion, rollback, offline selection, and refusal to fall back after online failure:

```sh
sudo env RIVET_BIN=/absolute/path/to/rivet bash scripts/test-distribution-linux.sh
```

This script mutates real host paths; use the same disposable-host boundary as other host workflows. Live S3/GCS exchange/signing, GCP metadata/JWKS, OIDC rotation, and deployment IAM/storage policy still require deployment validation. Local timings do not establish cloud latency or fleet capacity.

## Fern documentation

The site configuration is `fern/docs.yml`, with content in `fern/pages/` and SVG branding in `fern/assets/`. The project pins the installed Fern CLI version in `fern/fern.config.json`.

```sh
fern check --local --warnings
fern docs md check
fern docs dev --port 3000
```

Compile every complete HCL snippet using synthetic facts and temporary assets, without applying it:

```sh
cargo build --bin rivet --locked
python3 tests/documentation_examples.py
```

This check also asserts that every built-in function has a family reference and compiles the repository module/YAML, template, and hierarchy tutorials. Operational agent/server configurations and snippets requiring installed plugins or verified service claims use text fences because the checker compiles managed-resource HCL without an authenticated service. Their contracts are covered by the distribution tests above. The documentation checker covers compilation and bundle publication; real Linux convergence remains covered by the disposable host workflows.

Open the local URL printed by the dev server. Fern's local preview uses pnpm, which must be on PATH. Hosted search is unavailable in local development; search is disabled in configuration and feedback is hidden. The preview may still display an inactive search control. Use sidebar navigation or browser find. The config has an empty instance list and no publishing workflow. Do not use hosted preview or publishing commands for this local-only site.

Fern's [local preview documentation](https://buildwithfern.com/learn/docs/preview-publish/preview-changes) describes the dev workflow. Keep navigation and internal links synchronized; broken links are configured as errors. When changing language/resource docs, check the examples against `rivet validate` and the typed definitions, not only the future design specification.

Plugin manifest testing has a portable integration check:

```sh
cargo build --workspace --locked
python3 tests/plugin_manifest_testing_workflow.py target/debug/rivet target/debug/rivet-plugin-example
```

Pass your build's executable paths when using a custom Cargo target directory. The check covers external content and relationships, service options, functions, fact sets, expected diagnostics, plugin failures, and the absence of runtime RPCs. The disposable Linux `checks` suite also runs it.