diff --git a/README.md b/README.md index ae62defa..4953c173 100644 --- a/README.md +++ b/README.md @@ -33,8 +33,8 @@ coding agents (Claude Code / Codex) compose and evolve **typed dora-rs dataflows** against a **Genesis** physics scene, with frozen verification/reset and scoped safety structure. The scene contract is engine neutral; two optional engines run the same graphs for development, -[Nexus](docs/decisions/ADR-67.md) on the GPU and -[rapier](docs/decisions/ADR-68.md) on the CPU (`--sim-engine nexus|rapier`), +[Nexus](docs/simulation-backends.md#nexus) on the GPU and +[rapier](docs/simulation-backends.md#rapier) on the CPU (`--sim-engine nexus|rapier`), while Genesis stays the default and the only engine behind the measured record. @@ -236,6 +236,38 @@ uv run --extra sim --locked python tools/dora_runtime.py verify --prefix "$AISLE uv run --extra sim --locked python tools/quickstart.py --runtime-prefix "$AISLE_DORA_PREFIX" ``` +### Choose a simulation backend + +Genesis is installed by the `sim` extra and remains the default. Select it +explicitly, or choose an installed optional backend, with the same rollout +flag: + +```bash +# Default, measured backend +uv run --extra sim --locked harness rollout --graph graphs/expert_t0.yaml --tier T0 \ + --episodes 2 --seeds 0..1 --no-idea-gate --env-baseline local \ + --sim-engine genesis + +# Optional GPU backend: install after `uv sync --extra sim --locked` +uv run --no-sync python tools/nexus_runtime.py install +uv run --no-sync python tools/nexus_runtime.py verify +uv run --no-sync harness rollout --graph graphs/expert_t0.yaml --tier T0 \ + --episodes 2 --seeds 0..1 --no-idea-gate --env-baseline local \ + --sim-engine nexus + +# Optional CPU solver with the Nexus renderer +uv run --no-sync python tools/rapier_runtime.py install +uv run --no-sync python tools/rapier_runtime.py verify +uv run --no-sync harness rollout --graph graphs/expert_t0.yaml --tier T0 \ + --episodes 2 --seeds 0..1 --no-idea-gate --env-baseline local \ + --sim-engine rapier +``` + +See the [simulation backend guide](docs/simulation-backends.md) for platform +support, source receipts, backend overrides, direct graph declarations, and +current limitations. Nexus and rapier are development backends; do not compare +their results with the Genesis measured record. + The Python API remains pinned to 1.0.1; the CLI is built from the corrected, immutable source revision in `dora-runtime.json`. CLI version output alone does not identify that correction: the installer and quickstart verify its receipt. diff --git a/docs/getting-started.md b/docs/getting-started.md index 3dbfc584..b03e8d2e 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -33,6 +33,11 @@ Things to know before anything else: (#516). Install the corrected source pin rather than relying on version output, which is also 1.0.1 for the corrected binary. +Genesis is the default simulation engine. Nexus and rapier are optional source +builds installed after this locked environment; see the +[simulation backend guide](simulation-backends.md) for a comparison and the +shortest install, verify, and selection path. + On Ubuntu 24.04, install the CPU quickstart's rendering prerequisites. Genesis constructs an offscreen renderer even when physics runs on CPU: @@ -201,11 +206,11 @@ argument switches the whole build to local sources, so you never get a half-pinned, half-local mix. Then: ```bash -uv run --extra sim --locked pytest -m sim tests/sim/test_nexus_scene.py +uv run --no-sync pytest -m sim tests/sim/test_nexus_scene.py ``` ```bash -uv run --extra sim --locked harness rollout --graph graphs/expert_t0.yaml --tier T0 \ +uv run --no-sync harness rollout --graph graphs/expert_t0.yaml --tier T0 \ --episodes 2 --seeds 0..1 --no-idea-gate --env-baseline local --sim-engine nexus ``` @@ -236,15 +241,23 @@ uv run --no-sync python tools/rapier_runtime.py install `--rapier ../rapier` builds from a local checkout instead. -`--no-sync` matters here: a syncing `uv run` would reinstall the locked -environment first and take the Nexus wheel back out, which is the renderer -this engine needs. +Keep `--no-sync` on the installer and subsequent commands so no sync step runs +or changes the environment containing the out-of-lock Nexus wheel that this +engine needs for rendering. `tools/rapier_runtime.py verify` reports the solver's receipt and the renderer's together, so a half-installed environment is visible before a run rather than at the first render. Its engine constants live in `src/aisle/sim/rapier_physics.toml`, alongside the Nexus ones. +Run the same graph through rapier without another sync step: + +```bash +uv run --no-sync python tools/rapier_runtime.py verify +uv run --no-sync harness rollout --graph graphs/expert_t0.yaml --tier T0 \ + --episodes 2 --seeds 0..1 --no-idea-gate --env-baseline local --sim-engine rapier +``` + ## 4. Where to go next - `docs/physical-ai-primer.md` — the concepts behind the project diff --git a/docs/harness-guide.md b/docs/harness-guide.md index 1bb9f9fa..0a10ec41 100644 --- a/docs/harness-guide.md +++ b/docs/harness-guide.md @@ -54,7 +54,7 @@ the scene (ADR-67, ADR-68); it defaults to `genesis` and is recorded in the manifest as `sim_engine`, beside a digest of the engine realization and the wheel's build receipt. `nexus` (GPU) and `rapier` (CPU, rendering through the Nexus viewer) refuse before launch when their wheels are not installed -(see [getting started](getting-started.md) §3b and §3c), and results are not +(see the [simulation backend guide](simulation-backends.md)), and results are not comparable across engines. A graph whose bridge node declares `AISLE_SIM_ENGINE` owns the choice: passing a different `--sim-engine` is refused rather than silently overridden. The same flag is on @@ -62,7 +62,7 @@ refused rather than silently overridden. The same flag is on and `harness fleet`. ```bash -uv run harness rollout --graph graphs/expert_t0.yaml --tier T0 \ +uv run --no-sync harness rollout --graph graphs/expert_t0.yaml --tier T0 \ --episodes 2 --seeds 0..1 --no-idea-gate --env-baseline local --sim-engine nexus ``` diff --git a/docs/simulation-backends.md b/docs/simulation-backends.md new file mode 100644 index 00000000..09a8900a --- /dev/null +++ b/docs/simulation-backends.md @@ -0,0 +1,124 @@ +# Simulation backends + +AISLE can realize the same scene and bridge contract with three physics +engines. Select one with `harness rollout --sim-engine`; the harness injects +the choice into the bridge and records it in the run manifest. + +| Engine | Physics | Renderer | Installation | Status | +|---|---|---|---|---| +| `genesis` | Genesis | Genesis | Included in the `sim` or `cuda` extra | Default; only engine behind the measured record | +| `nexus` | Nexus GPU | Nexus | Build the pinned `nexus3d` wheel | Development only | +| `rapier` | Rapier CPU | Nexus | Build both `nexus3d` and `rapier3d` | Development only | + +Results from different engines are not directly comparable. Each run records +the engine, resolved backend and device, the engine realization digest, and +the optional wheel build receipt. + +## Genesis + +Genesis is installed with the normal simulation environment: + +```bash +uv sync --extra sim --locked +``` + +It is the default when `--sim-engine` is omitted. An explicit development +rollout is: + +```bash +uv run --extra sim --locked harness rollout --graph graphs/expert_t0.yaml --tier T0 \ + --episodes 2 --seeds 0..1 --no-idea-gate --env-baseline local \ + --sim-engine genesis +``` + +On NVIDIA Linux, use `uv sync --extra cuda --locked`, use `--extra cuda` on +the `uv run`, and add `--sim-extra cuda`. The CUDA request fails closed if no +CUDA device is available. + +## Nexus + +Nexus is outside `uv.lock`. The installer fetches the source commit pinned in +`engine-runtime.json`, builds the wheel with maturin, installs it into the +project environment, and writes `.nexus-runtime-receipt.json`. + +Start from the normal `sim` environment, then install and verify Nexus: + +```bash +uv sync --extra sim --locked +uv run --no-sync python tools/nexus_runtime.py install +uv run --no-sync python tools/nexus_runtime.py verify +``` + +Run a graph with Nexus: + +```bash +uv run --no-sync harness rollout --graph graphs/expert_t0.yaml --tier T0 \ + --episodes 2 --seeds 0..1 --no-idea-gate --env-baseline local \ + --sim-engine nexus +``` + +The default Nexus build feature is `metal` on macOS and `webgpu` elsewhere. +Use `tools/nexus_runtime.py install --feature ` when the wheel needs a +different compiled feature. `AISLE_SIM_BACKEND` accepts `metal`, `webgpu`, +`cuda`, or `cpu`, but ordinary rollouts should let the harness resolve and +attest the backend from `--sim-extra` and the host. + +To build a local Nexus checkout instead of the pinned source: + +```bash +uv run --no-sync python tools/nexus_runtime.py install --nexus ../nexus +``` + +## Rapier + +Rapier steps physics on the CPU and uses Nexus for rendering. Install Nexus +first, then build and verify the pinned Rapier Python bindings: + +```bash +uv sync --extra sim --locked +uv run --no-sync python tools/nexus_runtime.py install +uv run --no-sync python tools/rapier_runtime.py install +uv run --no-sync python tools/rapier_runtime.py verify +``` + +Run a graph with Rapier: + +```bash +uv run --no-sync harness rollout --graph graphs/expert_t0.yaml --tier T0 \ + --episodes 2 --seeds 0..1 --no-idea-gate --env-baseline local \ + --sim-engine rapier +``` + +`tools/rapier_runtime.py install --rapier ../rapier` builds a local checkout. +Add `--determinism` to build Rapier's enhanced determinism feature when the +experiment requires cross-platform math consistency. + +## Selection rules + +- `--sim-engine {genesis,nexus,rapier}` is available on `harness rollout`, + `harness fleet`, `harness monolith run`, `harness fault calibrate`, and + `harness skill register`. +- A graph can declare `AISLE_SIM_ENGINE` in its simulation bridge node. A + conflicting CLI selection is refused instead of silently overriding the + graph. +- For a direct `dora run`, set `AISLE_SIM_ENGINE` in the bridge node's `env` + mapping. Prefer the harness for recorded work because it validates, injects, + hashes, and records the engine choice. +- Nexus and Rapier require clean build receipts. A missing, malformed, or dirty + source receipt fails the environment gate before launch. + +## Keep optional wheels installed + +`uv sync` removes the out-of-lock Nexus and Rapier wheels. After either +optional installer runs, use `uv run --no-sync ...` for verification, tests, +and rollouts so no sync step runs or changes the installed environment. If a +command reports that an optional engine is not installed, rerun its installer +and verifier. + +More detail: + +- [Getting started](getting-started.md), including platform prerequisites +- [Harness CLI guide](harness-guide.md) +- [Troubleshooting](troubleshooting.md) +- [ADR-67: Nexus engine](decisions/ADR-67.md) +- [ADR-68: Rapier engine](decisions/ADR-68.md) diff --git a/docs/troubleshooting.md b/docs/troubleshooting.md index 7df8d0f2..049ed8fe 100644 --- a/docs/troubleshooting.md +++ b/docs/troubleshooting.md @@ -19,6 +19,8 @@ That sync also removes the optional engine wheels, silently: neither lock ([getting started](getting-started.md) §3b and §3c), so any `uv sync` drops them and `--sim-engine nexus` then refuses at the `sim_engine` gate with `simulation engine 'nexus' is not installed in this environment`. +The complete install and selection matrix is in the +[simulation backend guide](simulation-backends.md). Reinstall them from the commits `engine-runtime.json` pins: ```bash @@ -29,8 +31,8 @@ uv run --no-sync python tools/nexus_runtime.py install uv run --no-sync python tools/rapier_runtime.py install ``` -Keep `--no-sync` on those: a syncing `uv run` reinstalls the locked -environment first and takes the other engine wheel back out. +Keep `--no-sync` on the installers and subsequent commands so no sync step +runs or changes the environment containing the out-of-lock wheels. A pinned install that fails with `upload-pack: not our ref` means the pinned commit is not on the remote, usually because a local engine commit has not