OxideSwarm
Health Warn
- License — License: NOASSERTION
- Description — Repository has a description
- Active repo — Last push 0 days ago
- Low visibility — Only 6 GitHub stars
Code Pass
- Code scan — Scanned 12 files during light audit, no dangerous patterns found
Permissions Pass
- Permissions — No dangerous permissions requested
No AI report is available for this listing yet.
Run builds and tests on the machines you already own: one Rust binary turns Macs, Windows PCs and Linux boxes into an encrypted compute grid for you and your coding agents (MCP).
OxideSwarm
Zero-Broker Distributed Computing Grid for Heterogeneous Clusters
Apple Silicon, Windows GPU PCs, Android phones and Linux boxes working as one personal compute grid
1. Overview
OxideSwarm is a small distributed computing framework written in Rust. A master hands tasks (commands,
shell scripts, compile jobs, map/reduce chunks, GPU-class compute) to workers running on your own machines:
Apple Silicon MacBooks, Windows gaming PCs, Android phones and Linux servers.
- Zero external message brokers: Tokio actors, 4-byte length-delimited TCP streams and QUIC. No Redis, Kafka, RabbitMQ or ZooKeeper.
- P2P NAT traversal (
iroh): QUIC with DERP relay fallback connects machines on different networks without opening router ports or setting up a VPN (needs outbound Internet to the public n0 relays). - Shared-secret authentication & stream encryption: only machines holding the same
cluster.secretcan join the grid or drive it, and workers only obey a master that proves it holds the secret. Authenticated TCP connections encrypt wire traffic post-handshake using ChaCha20-Poly1305 (0x04) with directional keys derived from the shared secret, while maintaining transparent backward compatibility for unauthenticated loopback dev/test runs. See docs/SECURITY.md. - Light background worker: built as a single native Rust binary without external runtimes (
windows\status_worker.cmdinspects the live working-set RAM of the running worker). The Windows runner starts headless, without console windows. - Quick role swapping and discovery:
switch_role.sh/windows\switch_role.cmdturn a machine into a master or a worker in a few seconds. Workers can find a master with--master auto(authenticated UDP beacon on:8089). - Decoupled 4-layer layout: Rust core engine, Android JNI bridge, Agent Mesh coordination hub, cross-machine sync/benchmarks.
- Process-tree lifecycle and bounded memory: task process trees are terminated (
taskkill /F /T/ process groups), with LRU task eviction and stale-worker pruning on the master. - Task placement and a cluster check: pin a task to an OS, an architecture, a tag or one worker (
submit --os,--arch,--require-tag,--worker), send a script and input data with it, and verify a running cluster withoxideswarm doctor.
Documentation index and writing standard: docs/README.md. A macOS + Windows walk-through, verified end to end: docs/guides/two-machine-cluster.md.
2. Architecture & Cluster Topology
┌──────────────────────────────────────────────┐
│ OXIDESWARM MASTER │
│ (MacBook M-Series OR Windows GPU PC) │
│ Cluster TCP :8088 (secret-authenticated) │
│ Dashboard :8080 (token; loopback default)│
│ UDP LAN discovery beacon :8089 │
└───────────────▲───────────────▲──────────────┘
│ │
Outbound TCP │ │ Outbound TCP / QUIC
(Auto-Reconnect) │ │ (P2P ticket + secret)
│ │
┌───────────────────────────────────┴─┐ ┌─────────┴─────────────────────────────┐
│ MOBILE COMPUTE NODE │ │ WINDOWS GPU COMPUTE NODE │
│ ARM64 Mobile Node (Galaxy/Pixel) │ │ Windows Workstation / GPU Rig │
│ 10 Cores Physical (ARM64) │ │ (x86_64 + NVIDIA/AMD GPU) │
│ • Termux worker or JNI app │ │ • headless background worker │
│ • Auto-cutoff on low battery (<15%)│ │ • Standby portal HTTP 307 redirect │
│ • Thermal throttling protection │ │ • Anti-stuttering host protection │
└─────────────────────────────────────┘ └───────────────────────────────────────┘
3. Capabilities & Status
Status values use the fixed vocabulary: Implemented, Partial, Planned, or Design only.
| Category / Feature | What it is | Status |
|---|---|---|
| 1. Core grid & zero-broker | Wire protocol with 4-byte length-delimited framing and dual-mode Serde; 1-byte format discriminator (0x02 bincode, 0x01 tagged JSON, 0x7B raw legacy JSON, 0x03 auth handshake, 0x04 AEAD encrypted). |
Implemented |
| 2. Master coordinator & scheduler | 8-state FSM (Submitted ➔ Queued ➔ Scheduled ➔ Running ➔ Completed / Failed / Retrying / Cancelled), batch-spread scheduling, fast-path recovery when a worker's socket drops (asserted below 200 ms in tests/m2_challenger_2_stress.rs), 10 s heartbeat reaper. |
Implemented |
| 3. GPU workload routing | Tasks that require a GPU go only to workers that advertise one. A worker advertises a real GPU only if its binary was built with --features gpu-wgpu and the compute engine started on an adapter (looked for automatically at start-up unless --no-gpu; --gpu insists and prints a warning when that is not possible); a build without wgpu advertises none. --simulate-gpu advertises a labelled simulated GPU (a CPU multiplication, for testing) and is eligible as well; the master scheduler strictly prioritizes idle hardware GPU (wgpu) workers over simulated GPU (--simulate-gpu) workers for GPU tasks. |
Implemented |
| 4. Anti-stuttering backpressure | Host CPU/RAM telemetry via sysinfo; above 85 % CPU (--max-host-cpu-pct) the master defers dispatches to that worker. |
Implemented |
| 5. In-memory Map/Reduce | Chunking, built-in word_count / line_count / identity and sum / count / max / min / concat kernels, local script shipping (--mapper ./map.sh, --reducer ./reduce.sh), or worker commands (--map-cmd, --reduce-cmd). Design: docs/design/0016-mapreduce-cli-script-shipping.md. |
Implemented |
| 6. Heterogeneous hardware | macOS, Linux, Android (ARM64), and Windows (x86_64) build targets; see the dated per-platform verification table below. Windows binaries cross-compile (build_windows_worker.sh); Windows launchers (.ps1, .cmd, .vbs) are checked statically by tests/test_launcher_scripts.py, not executed in automated tests. |
Partial |
| 7. Headless Windows worker | windows/run_worker_silent.vbs starts a worker without console windows (it needs the master's cluster.secret first); windows/status_worker.cmd shows the real working set; windows/stop_worker.cmd stops only the process it started. No PowerShell, .cmd, or .vbs file runs in any automated test (tests/test_launcher_scripts.py checks file text only). |
Partial |
| 8. Role swapping | switch_role.sh (macOS/Linux) and windows/switch_role.cmd: stop whatever this launcher started, start the new role, wait until it is up (the macOS/Linux script also checks that a worker registered) and print the next steps. Takes a few seconds. There is no automatic failover or election; a person (or script) decides. | Implemented |
| 9. Master discovery & fallback | Multi-tier coordinator discovery: Tier 1 LAN UDP beacon on :8089 (--master auto) and the :8080 standby HTTP 307 redirect portal work; Tier 2 HTTP probe (GET /api/discovery/probe?nonce=<hex>, served on the dashboard listener, which is loopback by default) and Tier 3 rendezvous registry (--rendezvous <URL> / OXIDESWARM_RENDEZVOUS) have remaining gaps (see FEAT-7 in docs/BACKLOG.md). Design: docs/design/0004-mcp-and-discovery.md. |
Partial |
| 10. Web dashboard | Axum server serving the SPA crates/master/src/dashboard.html (no CDN) plus REST, /ws and SSE. Loopback by default; reachable from phones/LAN only when you pass --web-ui-addr 0.0.0.0:8080 (or switch_role.sh master --dashboard-lan); every request off the dev bypass needs the token printed by oxideswarm secret show --dashboard-token. |
Implemented |
11. Workflow modes (ox-mode) |
test (quick / lint / flaky / full), dev (fast check / local cluster on 127.0.0.1:9090 and 127.0.0.1:8080 with automatic ephemeral-port fallback when either port is in use / watch / status discovering the dashboard port through .dev_cluster.json or --port / RUSTY_GRID_DASHBOARD_PORT), doc (build / verify with relative-link checks / generated spec summary export), research (profile / bench with Bincode wire-codec roundtrips / labeled synthetic scheduling simulation / report). Design: docs/design/0027-ox-mode-honest-reporting.md. |
Implemented |
| 12. Benchmarks & chaos | run_cluster_benchmark.sh measures parallel SHA-256 task throughput across two local worker processes (or a phone with --adb-id), and run_chaos_test.sh starts its own cluster, kills a worker that holds running tasks, and verifies re-execution. |
Implemented |
| 13. Zero-copy I/O & QUIC multiplexing | bytes::Bytes payloads; two iroh streams per connection (STREAM_CONTROL = 0x01, STREAM_DATA = 0x02) so bulk data cannot block heartbeats; scheduler micro-batching. |
Implemented |
| 14. Mid-task checkpointing | WorkerMessage::Checkpoint / MasterMessage::AssignTaskWithCheckpoint: WorkerClient passes the checkpoint sender to every task (client.rs:1670), and BuiltinTest, Generative3D, and AutoRig emit WorkerMessage::Checkpoint (runner.rs:2087, :2225, :2315), but Generative3D and AutoRig ignore the checkpoint on resume (_checkpoint, runner.rs:1909, :2286) and only the hash branch of BuiltinTest resumes (runner.rs:903-908). |
Partial |
15. GPU compute (wgpu) |
cargo build --release --bin oxideswarm --features gpu-wgpu gives a worker that multiplies matrices on the machine's GPU (Metal on macOS, Vulkan / DirectX 12 on Windows and Linux; discrete GPU prioritized over integrated), checks the product against a sampled CPU recomputation and reports Status: VERIFIED_OK only if that check passed. A GpuCompute task is a seeded simulated_matrix_dim x simulated_matrix_dim GEMM tiled by work_group_size. A GPU error, device loss or driver panic fails that task with an explicit message and the engine is rebuilt for the next one. A worker never runs a real-GPU task on the CPU: the CPU path is the labelled --simulate-gpu test mode only. Run benchmark with cargo run --release -p rusty_grid_worker --features gpu-wgpu --example gemm_bench -- 1024. |
Implemented |
| 16. Security | Shared-secret mutual authentication on the cluster port (TCP and P2P) and on the UDP beacon; authenticated TCP stream encryption via ChaCha20-Poly1305 (0x04) with directional keys derived from cluster.secret; token-protected, same-origin dashboard; agent-mesh hub token. See docs/SECURITY.md. |
Implemented |
| 17. Agent Mesh ↔ Grid bridge | AgentGridBridge lets agent-mesh hub run a Master Grid of its own (--grid-master <ADDR> starts an embedded master; off loopback it needs a cluster secret or --insecure) and routes grid_compute / grid_compile / grid_submit / grid_status envelopes to it. When unconfigured, returns ERR_BRIDGE_NOT_CONFIGURED. |
Implemented |
| 18. Task placement & cluster check | Workers advertise reserved system tags (os:, arch:, slots: for --max-concurrency or default headroom, iso:, tool: for start-up probed cargo, rustc, git, plus master-stamped id:, state:, link:) and user tags (worker --tag); submit --os, --arch, --worker, --require-tag, --require-isolation, --require-tool pin a task through require: task tags (require:os=, arch=, worker=, tag=, iso=<fs|fs+net>, and tool=<name>), so the wire format is unchanged. submit --stdin-file, --script-file, --interpreter and --env send input with the task; --matrix-dim sizes a GPU task. oxideswarm cancel <ID> and oxideswarm result <ID> [--wait] [--output-dir <DIR>] cancel tasks or fetch results asynchronously (design 0010). oxideswarm doctor checks connection, every worker (with its isolation level, ISO column and isolation in --json), process start-up, every GPU and spreading. Design: docs/design/0001-two-node-readiness.md, docs/design/0014-worker-max-concurrency-slots-tag.md, docs/design/0039-agent-workspaces.md. |
Implemented |
| 19. Mobile coordination & battery governance | Multi-tier throttling $C_{\text{eff}} = \min(C_{\text{bat}}, C_{\text{therm}})$, RRC adaptive keepalive (10s/25s/60s), and pre-sleep evacuation; the 5-rule mobile master refusal matrix (check_mobile_master_eligibility, not called in production) and automatic coordinator election (ClaimMasterRole, never constructed in production and unconditionally refused by reject_master_role_claim in server.rs) are design only (there is no automatic failover; see row 8). Design: docs/design/0002-mobile-coordination.md. |
Partial |
| 20. Task input and output files | submit --input LOCAL[:SANDBOX] sends files and whole directories, --output PATTERN (*, ?, **) brings files back into --output-dir. Files move as BLAKE3-named blobs through a bounded store on the master (~/.oxideswarm/blobs, master --blob-dir / --blob-store-mb) in 4 MiB chunks: a client uploads only the blobs the master lacks, a worker fetches only the blobs its cache lacks (worker --blob-cache-mb), so an unchanged file is not sent twice. Outputs are capped per task (worker --output-limit-mb); RustCompilation returns the library or binary it built. Both the CLI and the MCP server (oxideswarm mcp) use this content-addressed blob plane. Design: docs/design/0006-content-addressed-data-plane.md. The older inline staging (at most 32 MiB, retained for wire compatibility and library callers) is design 0003. Task output validation and mandatory harvesting failure semantics are documented in docs/design/0013-task-output-validation-and-harvesting.md. |
Partial |
| 21. Model Context Protocol (MCP) server | Concurrent JSON-RPC 2.0 stdio MCP server (oxideswarm mcp) exposing 6 core cluster tools (status, workers, submit, task_result, cancel, doctor) with content-addressed blob staging (files, outputs, output_dir), bounded head-and-tail stream formatting (max_output_bytes, captured_bytes, truncated, worker_truncated), client wait deadlines (wait_secs), notifications/cancelled, notifications/progress, pre-dispatch -32602 argument validation, and strict stdout hygiene. Design: docs/design/0004-mcp-and-discovery.md, docs/design/0012-mcp-concurrent-deadlines-and-cancel.md, docs/design/0022-head-and-tail-stream-capture.md. |
Implemented |
| 22. 3D generative engine names & CPU fallback | 3D generation tasks (submit --prompt <PROMPT>) default to CPU-capable procedural SDF generation and succeed on CPU-only worker nodes without requiring a GPU or --gpu. The --engine flag strictly enforces supported engines (sdf, triposr, auto), refusing unknown engine names with an informative error rather than silently falling back to auto. Design: docs/design/0015-engine-names-and-cpu-fallback.md. |
Implemented |
| 23. Generative 3D & Procedural SDF | Pure Rust procedural Signed Distance Field (SDF) mesh generation (Procedural-SDF-PureRust) for default (auto) and procedural (sdf) tiers, honest failure on missing neural model checkpoints, client-side pre-submission validation, and virtual environment isolation. Design: docs/design/0017-honest-3d-sdf-fallback.md. |
Implemented |
| 24. Agent Mesh command hardening & process controls | Restricts mesh nodes to 5 advertised commands (echo, ping, system_info, sha256_verify, shell_exec); unadvertised commands return exit 127. --no-shell flag filters out shell_exec capability and rejects execution requests with 127. Child processes inherit no stdin (DEVNULL), output is capped at 1 MiB per stream, and 5 secret env vars are stripped from parent environment inheritance. Design: docs/design/0011-agent-mesh-hardening.md. |
Implemented |
| 25. Head-and-tail task stream capture | Workers capture up to 10 MiB per output stream (stdout and stderr) using a split head-and-tail buffer (first 5 MiB + truncation notice + rolling last 5 MiB) so both startup banners and final build/test summaries survive when a task writes more than 10 MiB. MapReduceEngine checks both the legacy tail position and the midpoint position for [rusty_grid: output truncated after exceeding size limit]; upgrade the master before workers so an older master does not miss a midpoint marker. Design: docs/design/0022-head-and-tail-stream-capture.md. |
Implemented |
| 26. Agent workspaces | submit --workspace <NAME> (and the MCP workspace field) syncs the current directory, following .gitignore, into a named workspace on a worker started with --workspaces; only changed files travel, files deleted locally are deleted remotely, and build output such as target/ stays, so a second cargo test is incremental. One task per workspace at a time, with affinity to the worker that holds it (design 0039, guide). Measured on 2026-11-09 between a Mac and a Windows laptop: 207 s cold, 7 s warm (record). Symbolic links in the tree are skipped (W11) |
Implemented |
Per-Platform Verification Summary
| Platform | Target | Verified Path | Date | Notes |
|---|---|---|---|---|
| macOS (Apple Silicon) | aarch64-apple-darwin |
CI run 40269419930 at 3a1c120 and 41276400780 at c92d1dd (merge of PR #4, containing b76d85b; fmt, clippy, cargo test --workspace --lib --locked, audit: Pass); ./test_integration.sh (Pass), ./run_chaos_test.sh (Pass), python3 tests/test_launcher_scripts.py (Pass), cargo test --workspace --no-fail-fast (1392 passed, 19 failed in 9 test targets) at 3a1c120; cargo test --workspace --locked --no-fail-fast at 5b16f55 (1608 passed, 0 failed, 4 ignored across 117 test binaries, with both an empty temporary HOME and a dummy ~/.oxideswarm/cluster.secret in temporary HOME, TEST-4) |
2026-11-01 / 2026-11-08 | Recorded in docs/BACKLOG.md (Test baseline at 3a1c120 and status log for b76d85b / merge c92d1dd) and TEST-4 full-suite verification at 5b16f55 |
| Windows 11 (x86_64) | x86_64-pc-windows-msvc |
cargo test --workspace (1132 passed, 0 failed) and live 2-worker loopback cluster oxideswarm doctor --expect-workers 2 --gpu-dim 1024 (8 passed, 0 failed, including Vulkan 1024x1024 GEMM on RTX 5060 Ti and C6 spread, recorded in docs/design/0001-two-node-readiness.md and docs/guides/two-machine-cluster.md); CI runs 40269419930 (3a1c120) and 41276400780 (c92d1dd, merge of PR #4 containing b76d85b) (fmt, clippy, cargo test --workspace --lib --locked: Pass) |
2026-10-23 / 2026-11-01 | .ps1, .cmd, and .vbs files are checked statically by tests/test_launcher_scripts.py, not executed in tests |
| Ubuntu Linux (x86_64) | x86_64-unknown-linux-gnu |
GitHub Actions CI run 40269419930 at 3a1c120 and 41276400780 at c92d1dd (merge of PR #4, containing b76d85b; cargo fmt --all -- --check, cargo clippy --workspace --all-targets --locked -- -D warnings, cargo check -p rusty_grid_master --no-default-features --locked, cargo test --workspace --lib --locked, cargo audit: Pass) |
2026-11-01 | Recorded in docs/BACKLOG.md (Test baseline at 3a1c120 and INT-1 status log at b76d85b / merge c92d1dd) |
| Android (ARM64) | aarch64-linux-android |
Not run on a device. Host-side checks at 3a1c120 (docs/BACKLOG.md): crates/android_bridge unit tests in CI run 40269419930 (cargo test --workspace --lib --locked: Pass), and packaging/android/termux/start_worker.sh executed in a sandbox by tests/test_launcher_scripts.py:325-359 (Pass) |
2026-11-01 | Not run on aarch64-linux-android hardware; Kotlin app (packaging/android/app/) does not compile yet (see AND-1 in docs/BACKLOG.md) |
Known Limitations & Roadmap
| # | Limitation / Goal | Status | Technical details |
|---|---|---|---|
| 1 | Encrypted TCP stream transport | Implemented | After the cluster handshake (version 2) every frame is a ChaCha20-Poly1305 record (0x04) with directional keys derived from cluster.secret; a tampered, injected, replayed or reordered frame ends the connection, and peers that speak handshake version 1 are refused. No forward secrecy (see docs/SECURITY.md). Secret-less loopback dev/test runs stay plaintext. Documented in docs/design/0005-cluster-auth-v2-record-layer.md. |
| 2 | Automatic master failover & election | Design only | Authority scoring ($S_{\text{auth}}$), the 5-rule mobile refusal matrix (check_mobile_master_eligibility, not called in production), and MasterLeaseTicket exist in crates/core/src/arbitrage.rs, ProtocolCapabilities::ROLE_ARBITRAGE (1 << 7, protocol.rs:66) is not advertised in all_supported(), and all WorkerMessage::ClaimMasterRole arms in crates/master/src/server.rs call reject_master_role_claim to refuse every claim with RoleHandoverAck { accepted: false, task_queue_snapshot: Vec::new(), connected_workers: Vec::new() }; nothing constructs ClaimMasterRole in production and there is no automatic failover or election (switch_role.sh and windows/switch_role.cmd are manual; see row 8 above). Dynamic worker battery/thermal throttling ($C_{\text{eff}} = \min(C_{\text{bat}}, C_{\text{therm}})$) is documented in docs/design/0002-mobile-coordination.md. |
| 3 | MCP server for AI agents | Implemented | Concurrent JSON-RPC 2.0 stdio Model Context Protocol (MCP) server (oxideswarm mcp) exposing status, workers, submit, task_result, doctor, and cancel tools with content-addressed blob staging, bounded head-and-tail stream formatting, client wait deadlines (wait_secs), notifications/cancelled, strict JSON-RPC 2.0 framing (-32700, -32600, -32602), and strict stdout transport hygiene. Documented in docs/design/0004-mcp-and-discovery.md, docs/design/0012-mcp-concurrent-deadlines-and-cancel.md, and docs/design/0022-head-and-tail-stream-capture.md. |
| 4 | Real GPU scheduler preference | Implemented | Master scheduler strictly prioritizes idle hardware GPU (wgpu) workers over simulated GPU (--simulate-gpu) workers for requires_gpu tasks, dispatching to simulated workers only when no hardware GPU is available. |
| 5 | Android app cluster secret auth | Partial | crates/android_bridge exposes the nativeSetClusterSecret JNI export, and Kotlin WorkerEngine accepts clusterSecret to authenticate against protected masters (the Kotlin app itself does not compile yet; see AND-1 in docs/BACKLOG.md). |
| 6 | Task input and output files | Partial | Files and directories move as content-addressed blobs across both the CLI and the MCP server (master store, worker cache, 4 MiB chunks, nothing sent twice; design 0006). Not yet: compression, pipelined uploads from the CLI (one request in flight per connection, slow for thousands of small files over a high-latency link), .gitignore-aware selection (send src and Cargo.toml rather than a whole project with its target/), and symbolic links and empty directories inside input trees. Output validation, symlink rejection and mandatory harvest failure semantics are specified in design 0013. |
| 7 | UDP discovery on isolated subnets | Partial | 3-tier discovery hierarchy: Tier 1 LAN UDP beacon (:8089), Tier 2 authenticated HTTP probe (GET /api/discovery/probe?nonce=<hex>, served on the dashboard listener, which is loopback by default), and Tier 3 rendezvous registry (--rendezvous <URL> / OXIDESWARM_RENDEZVOUS). Tier 2 and Tier 3 have remaining limitations (see FEAT-7 in docs/BACKLOG.md). Documented in docs/design/0004-mcp-and-discovery.md. |
| 8 | Mid-task checkpointing | Partial | WorkerClient passes the checkpoint sender to every task (client.rs:1670), and BuiltinTest, Generative3D, and AutoRig send WorkerMessage::Checkpoint (runner.rs:2087, :2225, :2315), but Generative3D and AutoRig ignore the checkpoint on resume (_checkpoint, runner.rs:1909, :2286) and only the hash branch of BuiltinTest resumes from CheckpointData (runner.rs:903-908); all other task types and branches restart from the beginning when reassigned (see FEAT-5 in docs/BACKLOG.md). |
| 9 | OS child process containment | Implemented | On Windows, task child processes are bound to a Job Object (JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE with CREATE_SUSPENDED) to kill the process tree on worker termination, falling back to taskkill /F /T if job assignment fails. On Unix (Linux, macOS, Android), each task process group is watched by a double-forked lifeline-pipe supervisor (process_tree.rs) that kills the process group (SIGTERM then SIGKILL), any delegated Linux cgroup v2 leaf, and setsid() survivors matching the per-attempt RUSTY_GRID_RUN_TOKEN when the worker crashes or is killed with SIGKILL (docs/design/0031-containment-after-worker-crash.md). Start-up host capability probes (blender --version, sysctl, nvidia-smi, pmset, dumpsys, getprop, sw_vers, nvcc) are bounded to 3 s (HOST_PROBE_TIMEOUT). On Windows, resolve_windows_executable (runner.rs) resolves task executables across the fixed extension list [".com", ".exe", ".bat", ".cmd"] (in PATHEXT's default order) with a 2-byte MZ PE header check on .com/.exe and keeps Git for Windows usr\bin and bin ahead of PATH for bare names so extensionless files or 0-byte stubs cannot fail CreateProcessW with os error 193. Documented in docs/design/0009-blender-and-3d-process-supervision.md, docs/design/0020-bounded-host-capability-probes.md, docs/design/0025-windows-executable-resolution.md, and docs/design/0031-containment-after-worker-crash.md. |
| 10 | Protocol version & capability negotiation | Implemented | Workers, the master, and clients (ClientMessage and ClientResponse, protocol version 7) exchange and enforce protocol_version (PROTOCOL_VERSION_MIN_COMPATIBLE..=PROTOCOL_VERSION_CURRENT, with LEGACY_UNVERSIONED_PROTOCOL_VERSION = 2 for unversioned JSON frames and a pre-flight Hello check in connect_master before any state-changing command), WorkerClient gates runtime capabilities on the ProtocolCapabilities bits acknowledged in RegisterAck, and crates/core/src/wire_layout_tests.rs (plus CI against origin/master) requires bumping PROTOCOL_VERSION_CURRENT and PROTOCOL_VERSION_MIN_COMPATIBLE whenever recorded bincode bytes change. Documented in docs/design/0040-protocol-versioning.md. |
| 11 | 3D generative engine names and CPU fallback | Implemented | Default 3D generation executes on CPU worker nodes via procedural SDF without GPU hardware. Strict validation refuses unknown engine names across CLI, core builder, Agent Mesh bridge, and wire codecs (JSON and bincode). Documented in docs/design/0015-engine-names-and-cpu-fallback.md. |
| 12 | Honest 3D procedural SDF fallback | Implemented | Default (auto) and procedural (sdf) 3D generation routes to pure Rust Tier 0 Signed Distance Functions (Procedural-SDF-PureRust). Uninstalled neural checkpoints fail non-zero with explicit diagnostic reasons, --image inputs reject fast client-side, and subprocess failures propagate terminal stderr in result.error. Documented in docs/design/0017-honest-3d-sdf-fallback.md. |
| 13 | Exactly-once execution | Planned | Task delivery is at-least-once: if a worker disconnects, times out on heartbeats, or fails over after starting a task (or before the master processes its WorkerMessage::TaskResult, protocol.rs:443), the master requeues and dispatches the task to another worker, and the process tree of a killed worker can also keep running (run_chaos_test.sh:309), so a task can run twice. Tasks with external side effects must be idempotent. |
4. Quickstart Guide
Ports: 8088 is the cluster port (workers and submit / status talk to it), 8080 is the dashboard
(never a valid --master target), 8089/udp is discovery. Details: docs/SECURITY.md.
Quick start: offload cargo test to a second machine
Two machines on one network: on A you edit code (with or without a coding agent), B has Rust
installed and does the work. Neither machine has to build OxideSwarm.
Install the release archive for each system on both machines (Install).
Start the master on A. The first start creates
~/.oxideswarm/cluster.secret:oxideswarm master --listen 0.0.0.0:8088Join B with one token (design 0048). The token carries the
secret: move it over a channel you trust (never chat or e-mail), and pipe it in rather than
typing it as an argument:oxideswarm secret join-token --master <A_IP>:8088 > join.token # on A oxideswarm join < join.token # on B: saves the secret and the address, runs the doctor checks oxideswarm worker --workspaces # on BCheck from A that B offers workspaces and Cargo: in
oxideswarm workers --json, B'stags
includefeat:workspacesandtool:cargo.Offload from the root of a Rust project on A:
oxideswarm submit --workspace myproject --require-tool cargo --wait -- cargo testThe first run sends every file that
.gitignoredoes not exclude and builds from scratch. Run it
again: only changed files travel, and B reuses itstarget/directory.
To set up several machines, a USB stick can carry the program for every system and the token:
see packaging/usb/README.md. It installs, joins and starts the worker
with one double-click.
A coding agent does step 5 through oxideswarm mcp (guides/mcp-client-setup.md):
its submit tool takes the same workspace and tools fields. The full walk-through, with the
expected output, the MCP calls and troubleshooting, is
guides/offload-cargo-test.md, and measured times are in
benchmarks/grid/README.md.
Install
Download the archives from the Releases page
(the first release is v0.1.0), or build from source (Step 0 below).
Each release carries one archive per system, oxideswarm-<version>-<target>.tar.gz (Linux, macOS) or.zip (Windows), and a -gpu variant built with --features gpu-wgpu for a worker whose GPU should
do work. Targets: x86_64-unknown-linux-gnu (built on Ubuntu 22.04, needs glibc 2.35 or newer), aarch64-apple-darwin, x86_64-apple-darwin,x86_64-pc-windows-msvc. An archive holds oxideswarm, rusty-grid, ox-mode, the licences and the
installer scripts for that system under scripts/. SHA256SUMS lists every archive.
# macOS / Linux: verify, unpack, put the binaries on PATH (the file names below are an example)
shasum -a 256 -c SHA256SUMS --ignore-missing # Linux: sha256sum -c SHA256SUMS --ignore-missing
tar -xzf oxideswarm-0.1.0-aarch64-apple-darwin.tar.gz
# The binaries are not signed or notarized: a browser download is quarantined and Gatekeeper refuses to run it.
xattr -dr com.apple.quarantine oxideswarm-0.1.0-aarch64-apple-darwin # macOS only
sudo install -m 755 oxideswarm-0.1.0-aarch64-apple-darwin/{oxideswarm,rusty-grid,ox-mode} /usr/local/bin/
oxideswarm --help
# Windows: compare the hash with the SHA256SUMS line, unpack, add the folder to PATH
(Get-FileHash .\oxideswarm-0.1.0-x86_64-pc-windows-msvc.zip -Algorithm SHA256).Hash
Expand-Archive .\oxideswarm-0.1.0-x86_64-pc-windows-msvc.zip -DestinationPath C:\oxideswarm
$user = [Environment]::GetEnvironmentVariable('Path', 'User')
[Environment]::SetEnvironmentVariable('Path', "$user;C:\oxideswarm\oxideswarm-0.1.0-x86_64-pc-windows-msvc", 'User') # then open a new terminal
Then continue with Step 1 (master, worker, submit). The background-service installers inscripts/ (install_mac_daemon.sh --bin <PATH>, install_windows_service.ps1) take the unpacked rusty-grid binary.
Step 0: Build (from source)
cargo build --release --bin oxideswarm --bin rusty-grid # the two names are the same program
# Add --features gpu-wgpu on a machine whose GPU should do work (Apple Silicon Mac, Windows GPU PC);
# without it the worker cannot use the GPU and advertises none:
cargo build --release --bin oxideswarm --features gpu-wgpu
Step 1: Start the master and share the secret
# macOS / Linux: cluster port 8088 on every interface, dashboard on this machine only, plus a local worker
./switch_role.sh master
./switch_role.sh master --p2p # also publish a P2P ticket for machines on other networks (step D)
./switch_role.sh master --dashboard-lan # also open the dashboard (:8080) to phones / the LAN
./switch_role.sh master --no-worker # master only
# the same by hand
./target/release/oxideswarm master --listen 0.0.0.0:8088
./target/release/oxideswarm master --listen 0.0.0.0:8088 --p2p --p2p-ticket-file ~/.oxideswarm/master_ticket.txt
Windows master: windows\switch_role.cmd master [--p2p] [--lan-dashboard].
The first start of a master that other machines can reach creates ~/.oxideswarm/cluster.secret and prints
where it is. Copy that file to every machine that should join (workers and anyone running submit), over a
channel you trust, for example:
scp user@master:~/.oxideswarm/cluster.secret ~/.oxideswarm/cluster.secret && chmod 600 ~/.oxideswarm/cluster.secret
(Windows: %USERPROFILE%\.oxideswarm\cluster.secret; a USB stick works too. Never chat, e-mail or cloud-synced folders.)
Quick path: join with one token. Instead of copying the file and typing the address, create a token on the
master and pipe it into oxideswarm join on the new machine (the token is as sensitive as the secret: send it over a
channel you trust, never through chat or e-mail, and never as a command line argument):
# on the master
./target/release/oxideswarm secret join-token --master 192.168.1.100:8088 > join.token
# on the new machine (token on standard input; saves the secret at mode 600 and the address, then runs the doctor checks)
./target/release/oxideswarm join < join.token && ./target/release/oxideswarm worker
A master bound to loopback only (plain oxideswarm master) needs no secret. The dashboard token isoxideswarm secret show --dashboard-token. More: docs/SECURITY.md.
Step 2: Connect compute workers
For a Mac and a Windows PC, follow docs/guides/two-machine-cluster.md: it covers
the link (Wi-Fi, Ethernet, P2P), both roles and the check with oxideswarm doctor.
A. Windows GPU rig (headless background worker)
Put the master's cluster.secret into %USERPROFILE%\.oxideswarm\, then in the windows\ folder:
- Double-click
windows/run_worker_silent.vbs(looks for the master withauto), or - run
windows\switch_role.cmd worker <MASTER_IP>:8088, orwindows\start_worker.cmd <MASTER_IP>:8088
(the worker uses the GPU only ifrusty-grid.exewas built with--features gpu-wgpu, e.g../build_windows_worker.sh --gpu; it then finds the card itself and prints the adapter at start-up, and
without that feature it says so and advertises no GPU, also with--gpu), or - install a service that starts at boot:
windows\install_service.cmd <MASTER_IP>:8088 C:\path\to\cluster.secret
(runs as the low-privilege virtual accountNT SERVICE\OxideSwarmWorker, not SYSTEM; see
packaging/windows/README.md).
B. Android phone (Samsung Galaxy / Pixel)
- Termux worker (works with the secret today):
packaging/android/termux: runinstall_termux_daemon.sh, put the master's cluster address (<MASTER_IP>:8088) and the copied secret in place,
thenstart_worker.sh --daemon. - Android app (JNI): build
liboxideworker.sofirst withpackaging/android/build_android_jni.sh --release
and then the APK (guide). Supports native cluster secret configuration vianativeSetClusterSecret(note: the Gradle APK project inpackaging/android/app/does not compile yet; seeAND-1in docs/BACKLOG.md). - Dashboard from the phone: start the master with
--dashboard-lan, openhttp://<MASTER_IP>:8080and log in with
the token fromoxideswarm secret show --dashboard-token. The page's "Scan Master" button probes the current
host, hosts saved in the browser and hosts the master lists in/api/status; it does not scan your subnet.
C. Instant role swapping (promote Windows to master)
- On the Windows PC:
windows\switch_role.cmd master(or menu option1). - On the Mac:
./switch_role.sh worker <WINDOWS_IP>:8088(or menu option2).
Both machines need the samecluster.secretfirst. Nothing else is killed: the launchers stop only the processes
they started (PID files in~/.oxideswarm/run).
D. Remote WAN Connection (Cross-Network / Internet — requires Ticket AND Secret)
When two machines are on different networks (e.g., laptop on remote Wi-Fi, desktop compute node at home/office):
- On the Master coordinator, enable P2P:
./switch_role.sh master --p2p(oroxideswarm master --listen 0.0.0.0:8088 --p2p --p2p-ticket-file ~/.oxideswarm/master_ticket.txt). The master requires outbound Internet access to reach public Iroh (n0) DERP relays.- The connection ticket is written to
~/.oxideswarm/master_ticket.txt, printed in console output, or copied via the "📋 Copy P2P Ticket" button in the Web Dashboard. - The ticket remains deterministic across restarts if
~/.oxideswarm/master_key.binis preserved and relays are reachable during startup.
- The connection ticket is written to
- Copy the cluster secret
~/.oxideswarm/cluster.secretfrom the Master to the worker machine viascp, SSH, or physical USB drive. The P2P ticket provides address routing only and does not establish authorization; workers refuse pairing if the secret is missing (unless--insecureis explicitly passed). - On the Worker machine:
- macOS / Linux: Run
./connect_remote.sh "<TICKET>" --secret-file /path/to/cluster.secret(or execute without arguments to paste interactively). The ticket is persisted to~/.oxideswarm/remote-worker.toml(mode 0600) without modifying default configs. Pass--serviceto install a user-level LaunchDaemon on macOS. - Windows: Double-click
connect_remote.cmdand paste the ticket when prompted (avoid passing JSON via command-line arguments to prevent shell character stripping). The script requests elevation, installs theOxideSwarmWorkerservice under the virtual accountNT SERVICE\OxideSwarmWorker, and awaits registration confirmation.
- macOS / Linux: Run
- Automated Path Routing:
- Nodes attempt UDP hole-punching for direct zero-broker connectivity (
🟢 Direct P2P | <RTT>ms). - If UDP traffic is restricted by carrier CGNAT or firewalls, traffic automatically routes through encrypted HTTPS relays (
🟣 DERP Relay | <RTT>ms). - Comparative performance benchmarks are documented in the Interconnect Benchmark Report.
- P2P communication is encrypted via TLS by Iroh, in addition to HMAC-SHA256 cluster secret verification.
- Nodes attempt UDP hole-punching for direct zero-broker connectivity (
E. Cross-Machine Shared-Folder Probe (scripts/sync_network)
A lightweight utility for two machines sharing a cloud-synchronized folder (e.g., Google Drive, OneDrive, or local NFS/SMB share) to verify peer visibility:
- Role Assignment (SERVER / CLIENT): Mediated via ephemeral
claim_<platform>.jsontokens in the shared directory (claims older than 180 seconds are invalidated). - HTTP Ping on Port 8085: Direct reachability check between hosts; writes
ping_success.txtupon verification or generates detailed troubleshooting logs. - Process & Secret Isolation: The probe does not interact with the Rust compute grid (ports 8088, 8080, 8089) and never exchanges tickets or secrets. Secrets must never be stored in cloud-synced storage.
- For complete details, see scripts/sync_network/README.md.
Troubleshooting
Start with oxideswarm doctor --expect-workers <N> on any machine that holds the secret: it names the check that fails.
| Symptom | Likely cause and fix |
|---|---|
submit warns that no connected worker matches the placement constraints |
--os, --arch, --worker or --require-tag names something no connected worker has. The task waits in the queue; start that worker or fix the constraint (workers --json lists the os:, arch:, id: and user tags). |
Authentication required: ... / refusing to connect ... without a cluster secret (exit code 6) |
This machine has no (matching) secret. Copy ~/.oxideswarm/cluster.secret from the master, or pass --secret-file PATH. --insecure skips the check and is only for networks you fully control. |
Authentication failed |
The secrets differ, e.g. the master ran secret generate --force. Copy the master's file again and restart the worker. |
Worker logs Connection refused or times out |
Wrong port (use the cluster port 8088, not the dashboard's 8080); the master listens on loopback only (the default; start it with --listen 0.0.0.0:8088); a firewall blocks 8088. |
A worker started without --master never registers and logs P2P or Invalid P2P ticket errors |
A stale p2p_ticket sits in the config file the CLI auto-loads (RUSTY_GRID_CONFIG, ./rusty-grid.toml or ./rusty-grid.json — skipped by mcp — or ~/.oxideswarm/rusty-grid.toml). Pass --master HOST:8088 (which overrides [worker].p2p_ticket) or remove p2p_ticket from the config file. connect_remote.sh now writes remote-worker.toml instead and never touches rusty-grid.toml. |
submit fails with Task queue is full (<N> queued or running tasks; wait, or raise --max-queue-size) (exit code 1) |
The master has <N> active (queued, scheduled, running, or retrying) tasks and reached --max-queue-size. Wait for running tasks to finish, or restart the master with a higher --max-queue-size. |
--master auto finds nothing |
The UDP beacon (:8089) is not routed (Wi-Fi client isolation, another subnet, VPN) or the beacon's secret does not match. Use HOST:8088. |
Dashboard answers 401 or shows a login prompt |
Paste the token from oxideswarm secret show --dashboard-token (on the master). A phone can only reach the dashboard if the master was started with --web-ui-addr 0.0.0.0:8080 / --dashboard-lan. |
Address already in use on 8088 |
Another master, or the agent-mesh hub (it also defaults to 8088). Stop it or choose another port (OXIDESWARM_CLUSTER_PORT for the launchers, --listen by hand). |
| P2P pairing hangs | The master needs --p2p and Internet access to the public relays; the pairing machine needs the ticket and the secret. |
GPU tasks never reach the GPU / worker starts with "no GPU is advertised" |
The binary was built without the wgpu engine. Rebuild with cargo build --release --bin oxideswarm --features gpu-wgpu (Windows cross-build: ./build_windows_worker.sh --gpu); the worker prints GPU compute enabled on <adapter> at start-up when it works (see Capabilities #15). --gpu on a binary without the engine is ignored with a warning. |
A GPU task fails with GPU unavailable / GPU device error |
The worker advertised a GPU but the engine could not use it (no adapter, driver reset). The task failed instead of running on the CPU; the next task rebuilds the engine. Check the worker log. |
5. CLI Reference & Workflow Modes (ox-mode)
OxideSwarm includes a unified CLI management tool:
# Launch the interactive terminal UI (TUI) menu:
./ox-mode
# Code Quality & Testing Mode (Linting + Flaky test detection):
./ox-mode test lint
./ox-mode test flaky --iterations 5
# Development Mode (Live-reload file watcher and local dev cluster):
./ox-mode dev watch
./ox-mode dev cluster # binds 127.0.0.1:9090 and 127.0.0.1:8080 (or falls back to free ephemeral ports recorded in .dev_cluster.json)
./ox-mode dev status # probes the dashboard port from .dev_cluster.json (or --port / 8080)
./ox-mode dev stop
# Research & Performance Profiling Mode:
./ox-mode research bench
./ox-mode research distributed
Direct CLI commands (oxideswarm / rusty-grid)
oxideswarm and rusty-grid are the same program (rusty-grid is the older name; use either). Every command
accepts --help. Clients and workers read the cluster secret from --secret-file, OXIDESWARM_SECRET_FILE,
or ~/.oxideswarm/cluster.secret.
# Master. Default listen is 127.0.0.1:8088 (this machine only); other machines need 0.0.0.0:8088.
./target/release/oxideswarm master --listen 0.0.0.0:8088
# Persist the task queue across master restarts (snapshot.bin + journal.bin; defaults --blob-dir to <DIR>/blobs):
./target/release/oxideswarm master --listen 0.0.0.0:8088 --state-dir ~/.oxideswarm/state
# Raise active and finished-task memory budgets (each defaults to 256 MiB):
./target/release/oxideswarm master --listen 0.0.0.0:8088 --max-active-mb 512 --max-retained-mb 512
# Dashboard on the LAN as well (explicit; default is loopback):
./target/release/oxideswarm master --listen 0.0.0.0:8088 --web-ui-addr 0.0.0.0:8080
# Register with Tier 3 HTTP rendezvous registry:
./target/release/oxideswarm master --listen 0.0.0.0:8088 --rendezvous http://rendezvous.example.com:8080
# Join a machine with one token (design 0048): print on the master, read from standard input on the new machine
./target/release/oxideswarm secret join-token --master 192.168.1.100:8088 [--p2p-ticket-file ~/.oxideswarm/master_ticket.txt]
./target/release/oxideswarm join [--replace-secret] [--expect-workers N] [--no-doctor] < join.token
# Worker: --master takes the CLUSTER port (default 127.0.0.1:8088; a bare host gets :8088; 'auto' = LAN discovery)
./target/release/oxideswarm worker --master 192.168.1.100:8088
./target/release/oxideswarm worker --master 192.168.1.100:8088 # a --features gpu-wgpu build finds and uses the GPU itself
./target/release/oxideswarm worker --master 192.168.1.100:8088 --gpu # insist: warns and advertises no GPU if there is none / no wgpu
./target/release/oxideswarm worker --master 192.168.1.100:8088 --no-gpu # keep this machine's GPU out of the grid
./target/release/oxideswarm worker --master auto --rendezvous http://rendezvous.example.com:8080 # discover via Tier 3 fallback
# Submit work (--command is the executable, arguments follow after --; the file must exist on the worker)
./target/release/oxideswarm submit --master 127.0.0.1:8088 --command echo --wait -- hello
./target/release/oxideswarm submit --master 127.0.0.1:8088 --command sha256sum --wait -- /path/present/on/the/worker
./target/release/oxideswarm submit --master 127.0.0.1:8088 --type gpu --gpu --wait # routed to a worker that advertises a GPU
# Input and output files: send a file or a directory, bring back what the patterns select
# (files the master already holds are not sent again; outputs land in --output-dir at their sandbox paths; --output-dir requires --output)
./target/release/oxideswarm submit --input input.dat --output results.csv --output-dir out/ --command process_data -- input.dat results.csv
./target/release/oxideswarm submit --input ./my-crate:. --output 'target/release/my-crate' --output-dir out/ --timeout-secs 600 --command cargo -- build --release
./target/release/oxideswarm submit --input data/ --output 'reports/**/*.json' --type shell --script-file analyse.sh
# Worker with user tags (matched by `submit --require-tag`); os:/arch: tags are added automatically
./target/release/oxideswarm worker --master <MASTER_IP>:8088 --tag laptop --tag office
# A second worker on the same machine: give it its own name and no standby portal on :8080
./target/release/oxideswarm worker --master <MASTER_IP>:8088 --name <NAME>-2 --no-portal
# Pin a task to an OS, an architecture, a tag or one worker (a name, or an id from `workers --json`)
./target/release/oxideswarm submit --os windows --wait --command cmd -- /C ver
./target/release/oxideswarm submit --worker <WORKER_NAME> --wait -- uname -a
./target/release/oxideswarm submit --require-tag laptop --arch x86_64 --wait -- hostname
# Send input with the task (each file at most 32 MiB): a script, standard input, environment variables
./target/release/oxideswarm submit --type shell --interpreter python3 --script-file job.py --wait
./target/release/oxideswarm submit --stdin-file data.txt --env MODE=fast --wait --command wc -- -l
# GPU task of a chosen size (default 64; up to 8192 on a real GPU, 2048 on the simulated one)
./target/release/oxideswarm submit --type gpu --matrix-dim 2048 --wait
# 3D mesh generation: default runs on CPU via procedural SDF and writes a glTF 2.0 binary asset
./target/release/oxideswarm submit --prompt "a solid cube" -o cube.glb --wait
./target/release/oxideswarm submit --prompt "robot" --engine sdf -o robot.glb --wait
# Inspect the grid, fetch task results, or cancel a task
./target/release/oxideswarm workers --master 127.0.0.1:8088
./target/release/oxideswarm workspaces --master 127.0.0.1:8088
./target/release/oxideswarm status --master 127.0.0.1:8088 --json
./target/release/oxideswarm result <TASK_ID> --wait --output-dir out/
./target/release/oxideswarm cancel <TASK_ID>
# Persistent agent workspaces: sync a project tree once and reuse its build directory across runs
./target/release/oxideswarm submit --workspace oxideswarm --wait --command cargo -- test -p rusty_grid_core --lib
./target/release/oxideswarm submit --workspace oxideswarm --no-sync --cwd crates/core --wait --command cargo -- test --lib
./target/release/oxideswarm mapreduce --master 127.0.0.1:8088 --input data.txt --mapper word_count --reducer sum
# `--mapper` / `--reducer` ship local .sh scripts to workers; `--map-cmd` / `--reduce-cmd` run scripts/binaries that are already on every worker
./target/release/oxideswarm mapreduce --master 127.0.0.1:8088 --input data.txt --mapper ./map.sh --reducer ./reduce.sh
./target/release/oxideswarm mapreduce --master 127.0.0.1:8088 --input data.txt --map-cmd "python3 /tmp/map.py" --reduce-cmd "python3 /tmp/reduce.py"
# Model Context Protocol (MCP) stdio server for AI coding assistants
./target/release/oxideswarm mcp --master 127.0.0.1:8088
# Check the whole cluster: every worker, process start-up, every GPU, spreading
# (exit code 0 = all checks passed, 1 = a check failed, 6 = authentication failed)
./target/release/oxideswarm doctor --expect-workers 2
./target/release/oxideswarm doctor --json --skip-gpu
# Secret management
./target/release/oxideswarm secret generate
./target/release/oxideswarm secret show --dashboard-token
Exit code 6 means authentication failed. Remote or auto-discovered masters are refused without a secret unless
you pass --insecure (RUSTY_GRID_INSECURE=1, or insecure = true under [master], [worker], [submit], or [status] in rusty-grid.toml).
Complete CLI Flag Reference (oxideswarm / rusty-grid)
Every subcommand inherits the global flags below and responds to --help (-h) and --version (-V).
Global Flags (oxideswarm [GLOBAL_FLAGS] <SUBCOMMAND>)
| Flag / Alias | Default / Env / Config | Description |
|---|---|---|
-c, --config <PATH> |
RUSTY_GRID_CONFIG, ./rusty-grid.{toml,json}, ~/.oxideswarm/rusty-grid.toml |
Path to configuration file (oxideswarm mcp skips working-directory config files unless --config or RUSTY_GRID_CONFIG is set) |
-v, --verbose |
RUST_LOG=debug |
Enable verbose debug logging |
-q, --quiet |
RUST_LOG=error |
Suppress informational output (errors only) |
--secret-file <PATH> |
OXIDESWARM_SECRET_FILE, secret_file, ~/.oxideswarm/cluster.secret |
File containing the 64-hex-character cluster secret (mode 0600) |
--secret <HEX> |
OXIDESWARM_SECRET, secret |
Cluster secret as 64 hex characters (hidden from --help because command-line arguments are visible in ps; prefer --secret-file or OXIDESWARM_SECRET_FILE) |
-h, --help |
— | Print help information |
-V, --version |
— | Print version information |
oxideswarm master Flags
| Flag / Alias | Default / Env / Config | Description |
|---|---|---|
--listen <ADDR> |
127.0.0.1:8088 (RUSTY_GRID_MASTER_LISTEN, RUSTY_GRID_LISTEN, [master].listen) |
Grid TCP listen address (0.0.0.0:8088 to accept workers on other machines) |
--port-file <PATH> (alias --portfile) |
RUSTY_GRID_PORT_FILE, [master].port_file |
File path where the bound TCP grid port number is written |
--heartbeat-interval-secs <SECS> (alias --heartbeat-interval) |
3 (RUSTY_GRID_HEARTBEAT_INTERVAL_SECS, [master].heartbeat_interval_secs) |
Expected worker heartbeat interval in seconds |
--heartbeat-timeout-secs <SECS> (alias --heartbeat-timeout) |
10 (RUSTY_GRID_HEARTBEAT_TIMEOUT_SECS, [master].heartbeat_timeout_secs) |
Seconds without a heartbeat before a worker is marked dead |
--reaper-interval-secs <SECS> (alias --reaper-interval) |
1 (RUSTY_GRID_REAPER_INTERVAL_SECS, [master].reaper_interval_secs) |
Interval in seconds between dead-worker reaper sweeps |
--max-queue-size <N> |
Unbounded by count (RUSTY_GRID_MAX_QUEUE_SIZE, [master].max_queue_size) |
Maximum queued or running (non-terminal) tasks allowed in the queue at once (minimum 1; when full, oxideswarm submit exits 1 and advises waiting or raising --max-queue-size; --max-active-mb also bounds active queue memory) |
--scheduler-policy <POLICY> |
weighted (RUSTY_GRID_SCHEDULER_POLICY, [master].scheduler_policy) |
Load-balancing policy across eligible workers: weighted (weighted-least-loaded), least-loaded, or round-robin |
--default-retry-max <N> (alias --max-retries) |
3 (RUSTY_GRID_DEFAULT_RETRY_MAX, RUSTY_GRID_MAX_RETRIES, [master].default_retry_max) |
Default maximum execution retries per task |
--max-host-cpu-pct <PCT> |
85.0 (RUSTY_GRID_MAX_HOST_CPU_PCT, [master].max_host_cpu_pct) |
Host CPU percentage ceiling before anti-stuttering backpressure throttles dispatch |
--preserve-gpu <BOOL> |
true (RUSTY_GRID_PRESERVE_GPU, [master].preserve_gpu) |
Reserve GPU workers for GPU-requiring tasks when CPU-only workers are available |
--fail-unfulfillable-tasks [BOOL] |
false (RUSTY_GRID_FAIL_UNFULFILLABLE_TASKS, [master].fail_unfulfillable_tasks) |
When at least one connected (Connected or Busy) worker is schedulable, immediately fail tasks whose required capabilities or placement constraints no registered worker can satisfy (--fail-unfulfillable-tasks with no value sets true). A task whose only matching worker is Disconnected stays queued until that worker reconnects or is pruned 1 hour after its last heartbeat (ReaperConfig::stale_worker_timeout in crates/master/src/reaper.rs, no CLI flag), so a --wait caller blocks until then (or --timeout-secs). |
--p2p |
false (RUSTY_GRID_P2P, [master].p2p) |
Enable Iroh QUIC/DERP P2P endpoint for NAT traversal |
--relay-url <URL> |
n0 public relays (RUSTY_GRID_RELAY_URL, [master].relay_url) |
Custom https:// iroh relay URL (RelayMode::Custom on presets::Minimal; refused without https://, with user:password credentials, or when RUSTY_GRID_P2P_MINIMAL is enabled, design 0049) |
--p2p-ticket-file <PATH> |
RUSTY_GRID_P2P_TICKET_FILE, [master].p2p_ticket_file |
File path where the generated P2P connection ticket is written |
--p2p-key-file <PATH> (alias --key-file) |
~/.oxideswarm/master_key.bin (RUSTY_GRID_P2P_KEY_FILE, [master].p2p_key_file) |
Persistent P2P secret key file for stable NodeId and ticket across restarts |
--ephemeral-key |
false (RUSTY_GRID_EPHEMERAL_KEY) |
Force a random ephemeral P2P key instead of persisting master_key.bin |
--wire-codec <CODEC> |
bincode (RUSTY_GRID_WIRE_CODEC, [master].wire_codec) |
Wire format codec: bincode or json |
--web-ui-addr <ADDR> |
127.0.0.1:8080 |
Bind address for the embedded HTTP web dashboard (0.0.0.0:8080 exposes it on the LAN) |
--dashboard-port <PORT> |
8080 (RUSTY_GRID_DASHBOARD_PORT, OXIDE_SWARM_DASHBOARD_PORT, [master].dashboard_port) |
HTTP port for the embedded web dashboard (ignored if --web-ui-addr is given) |
--dashboard-port-file <PATH> |
RUSTY_GRID_DASHBOARD_PORT_FILE, OXIDE_SWARM_DASHBOARD_PORT_FILE, [master].dashboard_port_file |
File path where the bound dashboard HTTP port number is written |
--dev |
false (OXIDE_DEV_MODE) |
Enable local development mode (bypasses dashboard token auth on loopback interfaces only) |
--auth-token <TOKEN:NAME:SCOPES> |
Repeatable | Register an explicit dashboard API bearer token with comma-separated scopes (admin, submit, observer) |
--insecure |
false (RUSTY_GRID_INSECURE, [master].insecure) |
Allow a non-loopback or --p2p master to run without a cluster secret |
--max-retained-tasks <N> |
10000 (RUSTY_GRID_MAX_RETAINED_TASKS, [master].max_retained_tasks) |
Finished tasks retained in memory before evicting the oldest |
--max-retained-mb <MB> |
256 (RUSTY_GRID_MAX_RETAINED_MB, [master].max_retained_mb) |
Megabytes of finished-task payload and output retained in memory |
--max-active-mb <MB> |
256 (RUSTY_GRID_MAX_ACTIVE_MB, [master].max_active_mb) |
Megabytes of active (queued, scheduled, running, retrying) task payloads held at once (minimum 1) |
--state-dir <DIR> |
In-memory only (RUSTY_GRID_STATE_DIR, [master].state_dir) |
Directory of the durable task queue store (store.lock, snapshot.bin, journal.bin, mode 0700/0600 on Unix; persists task specs, env, stdin, and results in plaintext and defaults --blob-dir to <DIR>/blobs when --blob-dir is not set) |
--session-resume-hold-secs <SECS> |
30 (RUSTY_GRID_SESSION_RESUME_HOLD_SECS, [master].session_resume_hold_secs) |
Seconds a disconnected worker's running tasks are held for session resumption on every CLI master, even without --state-dir (0 disables the hold for immediate failover; library ServerConfig defaults to 0 without with_state_dir; maximum 3600, design 0046) |
--blob-dir <DIR> |
<state_dir>/blobs when --state-dir is set, else ~/.oxideswarm/blobs (RUSTY_GRID_BLOB_DIR, [master].blob_dir) |
Directory of the content-addressed blob store for task input and output files |
--blob-store-mb <MB> |
4096 (RUSTY_GRID_BLOB_STORE_MB, [master].blob_store_mb) |
Megabytes the master blob store holds before LRU eviction of unreferenced blobs |
--mapreduce-parallelism <N> |
256 (RUSTY_GRID_MAPREDUCE_PARALLELISM, [master].mapreduce_parallelism) |
Maximum map or reduce chunk tasks of one mapreduce job in flight at once |
--max-connections <N> |
1024 (RUSTY_GRID_MAX_CONNECTIONS, [master].max_connections) |
Maximum concurrent connections kept open on the grid port |
--max-pending-handshakes <N> |
64 (RUSTY_GRID_MAX_PENDING_HANDSHAKES, [master].max_pending_handshakes) |
Maximum connections allowed in the pre-authentication handshake state at once |
--rendezvous <URL> |
OXIDESWARM_RENDEZVOUS, RUSTY_GRID_RENDEZVOUS |
URL of Tier 3 HTTP rendezvous registry for cross-subnet discovery |
oxideswarm worker Flags
| Flag / Alias | Default / Env / Config | Description |
|---|---|---|
--master <ADDR|auto> |
127.0.0.1:8088 (RUSTY_GRID_MASTER_ADDR, RUSTY_GRID_MASTER, [worker].master) |
Master grid port address (HOST:8088, bare HOST, or auto for LAN discovery) |
--p2p-ticket <TICKET> |
RUSTY_GRID_P2P_TICKET, [worker].p2p_ticket |
Iroh P2P connection ticket for joining a remote master across NAT/WAN |
--relay-url <URL> |
n0 public relays (RUSTY_GRID_RELAY_URL, [worker].relay_url) |
Custom https:// iroh relay URL (RelayMode::Custom on presets::Minimal; refused without https://, with user:password credentials, or when RUSTY_GRID_P2P_MINIMAL is enabled, design 0049) |
--name <NAME> |
Hostname (RUSTY_GRID_WORKER_NAME, RUSTY_GRID_NAME, [worker].name) |
Worker node name override; persists worker UUID in ~/.oxideswarm/worker_id.<NAME> |
--tag <TAG> |
Repeatable (RUSTY_GRID_WORKER_TAGS, [worker].tags) |
User tag advertised to the master and matched by submit --require-tag |
--cores <N> (alias --cpu-cores) |
Auto-detected (RUSTY_GRID_CORES, RUSTY_GRID_CPU_CORES, [worker].cores) |
Override advertised CPU core count |
--ram-mb <MB> (aliases --override-ram-mb, --ram) |
Auto-detected (RUSTY_GRID_RAM_MB, RUSTY_GRID_OVERRIDE_RAM_MB, [worker].ram_mb) |
Override advertised RAM in megabytes |
--gpu |
false (RUSTY_GRID_GPU, RUSTY_GRID_ENABLE_GPU, [worker].gpu) |
Insist on a real hardware wgpu adapter (warns if unavailable or built without gpu-wgpu) |
--no-gpu |
false (RUSTY_GRID_NO_GPU, [worker].no_gpu) |
Never probe or advertise a GPU |
--simulate-gpu |
false (RUSTY_GRID_SIMULATE_GPU, [worker].simulate_gpu) |
Test mode: advertise a simulated GPU backed by CPU execution (is_simulated_gpu = true) |
--gpu-name <NAME> |
Auto-detected (RUSTY_GRID_GPU_NAME, [worker].gpu_name) |
Override advertised GPU model name |
--vram-mb <MB> |
Auto-detected (RUSTY_GRID_VRAM_MB, RUSTY_GRID_GPU_VRAM_MB, OXIDE_SWARM_VRAM_MB, [worker].vram_mb) |
Override advertised GPU VRAM in megabytes |
--cuda |
Auto-detected (RUSTY_GRID_CUDA, RUSTY_GRID_ENABLE_CUDA, OXIDE_SWARM_CUDA, [worker].cuda) |
Explicitly advertise CUDA support |
--no-cuda |
false (RUSTY_GRID_NO_CUDA, RUSTY_GRID_DISABLE_CUDA, OXIDE_SWARM_NO_CUDA, [worker].no_cuda) |
Explicitly disable CUDA support |
--blender |
Auto-detected (RUSTY_GRID_BLENDER, RUSTY_GRID_ENABLE_BLENDER, [worker].blender) |
Explicitly advertise headless Blender capability |
--no-blender |
false (RUSTY_GRID_NO_BLENDER, RUSTY_GRID_DISABLE_BLENDER, OXIDE_SWARM_NO_BLENDER, [worker].no_blender) |
Explicitly disable headless Blender capability |
--blender-path <PATH> |
Auto-detected (RUSTY_GRID_BLENDER_PATH, OXIDE_SWARM_BLENDER_PATH, BLENDER_PATH, [worker].blender_path) |
Path to Blender executable |
--blender-version <VER> |
Auto-detected (RUSTY_GRID_BLENDER_VERSION, [worker].blender_version) |
Override advertised Blender version string |
--max-concurrency <N> (alias --max-concurrent-tasks) |
max(1, cores - 1) (cores when --cores <N> is given; RUSTY_GRID_MAX_CONCURRENCY, RUSTY_GRID_MAX_CONCURRENT_TASKS, [worker].max_concurrency) |
Maximum concurrent tasks executed simultaneously on this worker |
--heartbeat-interval-secs <SECS> (alias --heartbeat-interval) |
3 (RUSTY_GRID_HEARTBEAT_INTERVAL_SECS, [worker].heartbeat_interval_secs) |
Fallback heartbeat interval in seconds |
--session-resume-grace-secs <SECS> |
Master hold window (RUSTY_GRID_SESSION_RESUME_GRACE_SECS, [worker].session_resume_grace_secs) |
Upper bound in seconds on how long running tasks keep executing across a master disconnect (0 disables session resumption on this worker, design 0046) |
--sandbox-base-dir <DIR> |
<TMPDIR or temp dir>/rusty_grid-<euid>/sandboxes on Unix (private mode 0700, design 0021) and %TEMP%\rusty_grid\sandboxes on Windows (RUSTY_GRID_SANDBOX_BASE_DIR, [worker].sandbox_base_dir) |
Base directory for isolated task execution sandboxes (used as given when set explicitly) |
--task-priority <PRIORITY> |
below-normal (RUSTY_GRID_TASK_PRIORITY) |
OS scheduling priority for task child processes: normal, below-normal, or idle |
--isolation <LEVEL> |
off (RUSTY_GRID_ISOLATION, [worker].isolation) |
OS-level confinement of task processes (design 0033): off; fs (a task writes only its own sandbox and cannot read the owner's home, other sandboxes, the blob cache or the shared temp areas; the Rust toolchain is read-only); fs+net (fs plus no network sockets). A confined task gets an allowlisted environment (PATH, LANG, LC_*, TERM, TZ, USER, LOGNAME, SHELL, COLORTERM, NO_COLOR, DEVELOPER_DIR, SDKROOT, RUSTUP_TOOLCHAIN, its own env, the RUSTY_GRID_* task variables), RUSTUP_HOME and CARGO_HOME pinned to the host's, and HOME and the temp variables inside its sandbox. macOS (sandbox-exec), Linux (Landlock for files, seccomp for sockets, io_uring and TIOCSTI, a private network namespace under fs+net when the host allows user namespaces; needs Linux 5.13+ with Landlock enabled, x86_64 or aarch64, and the worker refuses to start otherwise; signals to the worker are only blocked from Linux 6.12), and Windows (FEAT-3c: per-attempt AppContainer profile oxideswarm.task.<worker8>.<run_token>, custom capability SID oxideswarm.toolchain granted on toolchain roots at worker start-up and recorded in ~/.oxideswarm/windows_acl_grants.txt for windows/revoke-isolation-acls.ps1, WinCapabilityInternetClientSid + WinCapabilityPrivateNetworkClientServerSid under fs and zero network capabilities under fs+net, and a per-task private Desktop ox_desk_<pid>_<run_token>). A confined Linux task cannot create AF_UNIX sockets (ssh-agent, docker.sock and the D-Bus bus are out of reach; socketpair works) or use the kernel keyring and, under fs+net, no socket at all (the start-up log says whether a private network namespace is also available). $CARGO_HOME/config.toml is readable to tasks: keep registry tokens in credentials.toml. The worker also refuses to start when the cluster secret comes from OXIDESWARM_SECRET or --secret: on macOS a task running as the worker's user can read the environment and command line of every process of that user, so use --secret-file, OXIDESWARM_SECRET_FILE or the default file. Advertised as the reserved iso:<level> tag |
--keep-sandboxes |
false (RUSTY_GRID_KEEP_SANDBOXES, [worker].keep_sandboxes) |
Retain task sandbox directories after execution for debugging (skips both per-task teardown and the worker start-up leftover-sandbox sweep; a later worker start on the same --sandbox-base-dir without --keep-sandboxes sweeps any unlocked retained <task_id> directories) |
--blob-cache-mb <MB> |
2048 (RUSTY_GRID_BLOB_CACHE_MB, [worker].blob_cache_mb) |
Megabytes of task input/output blobs cached in <sandbox_base_dir>/cache/blobs |
--output-limit-mb <MB> |
1024 (RUSTY_GRID_OUTPUT_LIMIT_MB, [worker].output_limit_mb) |
Maximum megabytes of output files one task may return |
--workspaces |
false (RUSTY_GRID_WORKSPACES, [worker].workspaces) |
Enable persistent named workspaces on this worker (design 0039): opens the workspace store at start-up (refusing to start if the root fails the private-directory checks) and advertises ProtocolCapabilities::WORKSPACES (feat:workspaces) |
--workspace-root <PATH> |
<cache dir>/oxideswarm/workspaces ($XDG_CACHE_HOME or ~/.cache on Linux, ~/Library/Caches on macOS, %LOCALAPPDATA% on Windows; RUSTY_GRID_WORKSPACE_ROOT, [worker].workspace_root) |
Root directory of the persistent named workspace store |
--workspace-limit-mb <N> |
20480 (RUSTY_GRID_WORKSPACE_LIMIT_MB, [worker].workspace_limit_mb) |
Per-workspace disk quota in MiB (minimum 1); a workspace exceeding this limit after a run logs a warning to the task's stderr and is evicted first when idle |
--max-workspaces <N> |
8 (RUSTY_GRID_MAX_WORKSPACES, [worker].max_workspaces) |
Maximum number of persistent workspaces kept on disk before idle least-recently-used eviction (minimum 1) |
--no-portal |
false (RUSTY_GRID_NO_PORTAL, [worker].no_portal) |
Disable the worker standby HTTP redirect portal on :8080 (127.0.0.1:8080 when targeting a loopback master, 0.0.0.0:8080 otherwise) |
--wire-codec <CODEC> |
bincode (RUSTY_GRID_WIRE_CODEC, [worker].wire_codec) |
Wire format codec: bincode or json |
--insecure |
false (RUSTY_GRID_INSECURE, [worker].insecure) |
Allow connecting to a remote, auto, or P2P master without a cluster secret |
--rendezvous <URL> |
OXIDESWARM_RENDEZVOUS, RUSTY_GRID_RENDEZVOUS |
URL of Tier 3 HTTP rendezvous registry for cross-subnet discovery |
oxideswarm submit Flags
| Flag / Alias | Default / Env / Config | Description |
|---|---|---|
--master <ADDR|auto|TICKET> |
127.0.0.1:8088 (OXIDESWARM_MASTER, RUSTY_GRID_MASTER_ADDR, RUSTY_GRID_MASTER, [submit].master, [submit].p2p_ticket) |
Master grid port address (HOST:8088, bare HOST, auto, or an iroh P2P connection ticket) |
--relay-url <URL> |
n0 public relays (RUSTY_GRID_RELAY_URL, [submit].relay_url, [client].relay_url) |
Custom https:// iroh relay URL for client P2P connections (RelayMode::Custom on presets::Minimal; refused without https://, with user:password credentials, or when RUSTY_GRID_P2P_MINIMAL is enabled, design 0049) |
--type <TYPE> (alias --task-type) |
generic |
Task type: command (generic), shell, compile, gpu, 3d, or autorig |
--command <CMD> |
— | Executable name or shell snippet to run on the worker |
-- <ARGS>... |
— | Trailing command arguments passed to --command |
--cores <N> |
1 |
Minimum CPU cores required on the assigned worker |
--ram-mb <MB> (alias --ram) |
0 |
Minimum RAM in megabytes required on the assigned worker |
--gpu |
false |
Require a worker that advertises a GPU |
--timeout-secs <SECS> |
60 (1800 with --workspace; [submit].timeout_secs) |
Task execution timeout in seconds |
--max-retries <N> |
Master default | Maximum execution retries for this task |
--wait |
false (implied by --output and -o) |
Wait synchronously for task completion and print output |
--json |
false |
Emit submission/result output as JSON |
--os <OS> |
— | Pin to worker OS: macos (mac, darwin, osx), windows (win), linux, android |
--arch <ARCH> |
— | Pin to worker CPU architecture: x86_64 (amd64, x64), aarch64 (arm64) |
--worker <NAME|ID> |
— | Pin to a specific worker by name (case-insensitive) or UUID prefix |
--require-tag <TAG> |
Repeatable | Require a worker carrying this user tag (worker --tag) |
--require-tool <TOOL> |
Repeatable | Require a worker that advertises this host tool (tool:<name>, e.g. cargo, rustc, git) |
--require-isolation <LEVEL> |
— | Require a worker confined at least at fs or fs+net (worker --isolation); the constraint is require:iso=<level>, met when the worker's iso: tag is at that level or above (off < fs < fs+net; a worker without the tag counts as off) |
--source <PATH[:SANDBOX]> (alias --source-dir) |
Repeatable | Compile tasks: Rust source file or Cargo crate directory to compile (cargo build --offline when Cargo.toml is present, else rustc) |
--stdin-file <PATH> |
— | Command tasks: send a local file (at most 32 MiB) as standard input |
--script-file <PATH> |
— | Shell tasks: send a local script file (at most 32 MiB) to execute |
--interpreter <PROG> |
sh / cmd.exe |
Shell tasks: run the script with <PROG> (e.g. python3, bash) |
--env <KEY=VALUE> |
Repeatable | Set an environment variable in the task process |
--input <LOCAL[:SANDBOX]> (alias --file) |
Repeatable | Stage a local file or directory into the worker's task sandbox (deduplicated via blob store) |
--workspace <NAME> |
— | Run the task inside a persistent named workspace ([a-z0-9][a-z0-9._-]{0,63}) on a --workspaces worker (mutually exclusive with --input) |
--sync <DIR> |
Current directory (. when --workspace is set) |
Local directory to sync into --workspace before execution |
--no-sync |
false |
Run inside --workspace as it already exists on the worker without syncing local files |
--cwd <REL> |
Workspace root | Relative working directory inside --workspace for --command tasks |
--workspace-max-files <N> |
100000 |
Maximum file count scanned when syncing a --workspace source tree |
--workspace-max-mb <MB> |
2048 |
Maximum total megabytes scanned when syncing a --workspace source tree |
--output <PATTERN> (alias --expected-output) |
Repeatable | Glob/path pattern of sandbox files to collect after execution (implies --wait) |
--output-dir <DIR> |
Current directory | Local directory where collected --output files are written |
--matrix-dim <N> |
64 |
GPU tasks: square matrix dimension $N \times N$ (up to 8192 on physical GPU, 2048 on simulated GPU) |
--work-group-size <N> |
16 |
GPU tasks: compute shader workgroup tile edge length |
--prompt <TEXT> |
— | 3D generation tasks: text prompt describing the mesh to synthesize |
--image <IMAGE_PATH> |
— | 3D generation tasks: input image path (PNG, JPEG, WebP) |
--quality <QUALITY> |
standard |
3D generation quality preset: fast, standard, or high |
--engine <ENGINE> |
auto |
3D generation engine: auto, sdf (CPU procedural SDF), or triposr (Python engines/generative_3d/entrypoint.py) |
--export-texture |
true |
3D generation tasks: bake PBR UV texture maps into the output .glb |
--no-export-texture |
false |
3D generation tasks: disable texture map generation |
--input-mesh <MESH_PATH> |
— | Auto-rigging tasks: input mesh file (.glb, .gltf, or .obj) |
--rig-preset <PRESET> |
biped |
Auto-rigging skeletal preset: biped, quadruped, or generic |
--embed-animations <ANIMATIONS> |
— | Comma-separated animation clips to embed (e.g. idle,walk,turnaround) |
--preferred-provider <PROVIDER> |
builtin |
Auto-rigging provider: builtin (Rust skinning) or blender (headless Blender engines/autorig/blender_rig.py) |
-o, --output-asset <OUTPUT_PATH> (alias --glb-output) |
— | Destination path to write the generated or rigged .glb asset |
--insecure |
false (RUSTY_GRID_INSECURE, [submit].insecure) |
Allow submitting to a remote, auto, or P2P master without a cluster secret |
Inspection, MapReduce, Doctor, Secret, Mode & MCP Subcommands
| Subcommand | Flags / Aliases | Description |
|---|---|---|
oxideswarm status |
--master <ADDR|auto|TICKET>, --relay-url <URL>, --task-id <UUID> (alias --task), --workers, --json, --insecure |
Query cluster summary metrics, a specific task's status (--task-id), or connected workers (--workers) |
oxideswarm workers |
--master <ADDR|auto|TICKET>, --relay-url <URL>, --json, --insecure |
List connected workers with OS/arch, cores, RAM, GPU, tags, and running task counts |
oxideswarm workspaces |
--master <ADDR|auto|TICKET>, --relay-url <URL>, --json, --insecure |
List the master's workspace affinity map (name, worker, last_used_utc; lists the master's affinity map only, not the workspaces stored on workers, which needs W2b) |
oxideswarm result <ID> |
<ID>, --master <ADDR|auto|TICKET>, --relay-url <URL>, -w / --wait, --json, --output-dir <DIR>, --insecure |
Fetch stdout/stderr, exit code, and output blobs for task <ID> |
oxideswarm cancel <ID> |
<ID>, --master <ADDR|auto|TICKET>, --relay-url <URL>, --json, --insecure |
Cancel a queued or running task <ID> and terminate its worker process tree |
oxideswarm mapreduce |
--master <ADDR|auto|TICKET>, --relay-url <URL>, --input <FILE_OR_TEXT> (required, repeatable), --mapper <NAME_OR_SCRIPT> (default word_count), --map-cmd <CMD>, --reducer <NAME_OR_SCRIPT> (default sum), --reduce-cmd <CMD>, --chunks <N> (default 4), --timeout-secs <SECS> (default 60, [submit].timeout_secs), --json, --insecure |
Partition inputs across workers, run built-in (word_count, line_count, identity / sum, count, max, min, concat), local script (--mapper / --reducer), or worker command (--map-cmd / --reduce-cmd) stages |
oxideswarm doctor |
--master <ADDR|auto|TICKET>, --relay-url <URL>, --expect-workers <N> (default 1), --probe-timeout-secs <SECS> (default 60), --gpu-dim <N> (default 512), --spread-tasks <N>, --skip-gpu, --skip-spread, --skip-throughput, --json, --insecure |
End-to-end cluster verification across C1 (master reachable), C2 (worker count), C3 (pinned echo per worker), C4 (shell script per worker), C5 (GPU GEMM probe), C6 (multi-worker spread), C7 (link kind: warns for a relayed worker) and C8 (an 8 MiB blob moved to each worker, MB/s). The worker table has a LINK column (direct, relay, tcp plus the round-trip time) |
oxideswarm secret generate |
--out <PATH>, --force, --print |
Generate a 256-bit random cluster secret file (0600 permissions; default ~/.oxideswarm/cluster.secret) |
oxideswarm secret show |
--raw, --dashboard-token |
Show the resolved secret source + fingerprint, raw 64-char hex (--raw), or derived dashboard admin bearer token (--dashboard-token) |
oxideswarm secret join-token |
--master <HOST:PORT>, --p2p-ticket <TICKET>, --p2p-ticket-file <PATH> |
Print a join token (oxs1-join:...: the master address, an optional P2P ticket and the cluster secret, with an integrity tag) to stdout, with a warning on stderr. The token is as sensitive as the secret. Without --master, the [master] listen of the config file is used unless it is a wildcard |
oxideswarm join |
--replace-secret, --replace-master, --expect-workers <N> (default 0), --no-doctor |
Read a join token from standard input (piped, or pasted at a no-echo prompt on a terminal; an argument is refused), save the secret at mode 0600 (Windows: owner-only ACL) and the master address in ~/.oxideswarm/rusty-grid.toml (edited in place, comments kept, a private .bak-<time> backup first, never through a symlink), refuse a different secret configured via OXIDESWARM_SECRET*, --secret* or the config file, refuse to replace a different secret without --replace-secret or a different master or ticket without --replace-master, then run the doctor checks and exit with their status. Design: docs/design/0048-join-token.md |
oxideswarm mode [MODE] [ACTION] |
[MODE] (test, dev, doc, research), [ACTION], -a / --action-opt <ACTION>, --iterations <N> (default 5), --port <PORT> (RUSTY_GRID_DASHBOARD_PORT; without --port, dev status probes .dev_cluster.json then 8080), -i / --interactive, --json |
Run or inspect workflow modes (test, dev, doc, research) or open the interactive menu (--interactive) |
oxideswarm mcp |
--master <ADDR|auto|TICKET>, --workspace-max-files <N> (default 100000), --workspace-max-mb <MB> (default 2048), --insecure |
Run the Model Context Protocol (MCP) JSON-RPC 2.0 server over stdio |
agent-mesh CLI Subcommands (crates/agent_mesh)
| Subcommand | Flags | Description |
|---|---|---|
agent-mesh hub |
-l / --listen <ADDR> (default 127.0.0.1:8088), --token <TOKEN> (OXIDE_MESH_TOKEN), --insecure, --grid-master [<ADDR>] (OXIDE_GRID_MASTER), --secret <SECRET> (OXIDESWARM_SECRET), --max-active-mb <MB> (RUSTY_GRID_MAX_ACTIVE_MB) |
Start the WebSocket/HTTP Agent Mesh Relay Hub (and optional co-hosted Grid Master when --grid-master is passed) |
agent-mesh node (alias agent) |
--hub <URL> (default ws://127.0.0.1:8088/ws; supports wss://), --id <ID>, --platform <PLATFORM>, --no-shell, --token <TOKEN> (OXIDE_MESH_TOKEN), --tls-ca <PATH> (OXIDE_MESH_TLS_CA) |
Connect a persistent agent mesh node to the hub |
agent-mesh send |
--hub <URL>, --from <ID>, --to <ID>, -c / --command <CMD>, -a / --args <JSON>, --timeout-ms <MS>, --token <TOKEN> (OXIDE_MESH_TOKEN), --tls-ca <PATH> (OXIDE_MESH_TLS_CA) |
Dispatch a structured command to a mesh node via the hub |
agent-mesh list |
--hub <URL>, --from <ID>, --token <TOKEN> (OXIDE_MESH_TOKEN), --tls-ca <PATH> (OXIDE_MESH_TLS_CA) |
Query the catalog of active nodes connected to the hub |
agent-mesh data |
--hub <URL>, --from <ID>, --to <ID>, --payload <TEXT>, --token <TOKEN> (OXIDE_MESH_TOKEN), --tls-ca <PATH> (OXIDE_MESH_TLS_CA) |
Transmit a data payload with SHA-256 verification to a target node |
Network Port Topology
| Port | Protocol | Component | Role & Port Conflict Guidance |
|---|---|---|---|
| 8088 | TCP | Master Grid Coordinator | Primary cluster communication port for worker node registration, heartbeat exchanges, task distribution, and CLI client requests (submit, status, workers, mapreduce). Protected by mutual HMAC-SHA256 handshake (cluster_auth). |
| 8088 | TCP (WS/HTTP) | Agent Mesh Relay Hub | Default listener for agent-mesh hub. Critical Port Conflict: The default binding 127.0.0.1:8088 collides with the Master Grid port when co-located on the same physical host. Operators MUST bind the Hub to alternate ports (e.g. --port 8090) when co-locating services. |
| 8080 | HTTP | Master Dashboard & Worker Standby | Embedded Axum web server providing cluster telemetry, live status graphs, task submission, and WebSocket streams (/ws). Bound to loopback by default; requires explicit --web-ui-addr 0.0.0.0:8080 to expose across LAN. Protected by RBAC bearer tokens or derived cluster admin token (oxs1-dashboard-admin). When a standalone worker runs without a master on the same port, it binds 127.0.0.1:8080 when targeting a loopback master or 0.0.0.0:8080 otherwise to serve an HTTP 307 redirect to the discovered Master (worker --no-portal turns that off). |
| 8089 | UDP | Master Discovery Beacon | When the master listens on a non-loopback address, it binds 0.0.0.0:8089 and broadcasts its cluster address and optional dashboard URL to subnet broadcast (255.255.255.255:8089); when the master listens on loopback, it binds that loopback address (127.0.0.1:8089), answers local unicast probes only, and does not broadcast. When a cluster secret is present, beacon payloads include HMAC-SHA256 signatures to prevent rogue discovery spoofing. Workers with --master auto listen here. |
| 8085 | TCP (HTTP) | Cross-Machine Sync Probe | Standalone reachability probe used strictly by scripts/sync_network to verify LAN connectivity between nodes using cloud-shared mailboxes. Completely independent of the Rust grid runtime. |
| 8086 | TCP (HTTP, removed) | Former Secret Bootstrap Helper | Previously used by the removed agent_bridge.py serve-secret plain-HTTP secret transfer helper (SEC-4). No component opens port 8086; cluster secrets must be copied over an authenticated channel (scp, sftp, adb push, or physical media). |
Environment Variables Inventory
OxideSwarm resolves configuration through a 4-tier hierarchical engine:
$$\text{CLI Flags} > \text{Environment Variables} > \text{Configuration File (rusty-grid.toml)} > \text{Defaults}$$
Tier A: Core Authentication & Configuration Engine
| Variable | Component | Purpose |
|---|---|---|
OXIDESWARM_SECRET |
Global & Agent Mesh | 64-character hex cluster secret for mutual node authentication (--secret) |
OXIDESWARM_SECRET_FILE |
Global | File path pointing to cluster secret (--secret-file, mode 0600; preferred over inline hex) |
RUSTY_GRID_CONFIG |
Global | Path to TOML or JSON configuration file (--config) |
OXIDESWARM_HOME |
Global & Launchers | Base state directory override for cluster.secret, master_key.bin, worker_id, blobs, and launcher PID/log files (default: ~/.oxideswarm or %USERPROFILE%\.oxideswarm) |
RUST_LOG |
Global | Standard tracing_subscriber::EnvFilter directive overriding --verbose / --quiet |
Tier B: Master Coordinator & Scheduling
| Variable | Component | Purpose |
|---|---|---|
RUSTY_GRID_MASTER_LISTEN |
Master | Primary listen socket address for grid coordinator (--listen) |
RUSTY_GRID_LISTEN |
Master | Fallback alias for coordinator listen address |
RUSTY_GRID_PORT_FILE |
Master | File path where bound TCP port number is written (--port-file) |
RUSTY_GRID_HEARTBEAT_INTERVAL_SECS |
Master & Worker | Heartbeat interval in seconds (--heartbeat-interval-secs; default 3) |
RUSTY_GRID_HEARTBEAT_TIMEOUT_SECS |
Master | Liveness timeout before worker is marked dead (--heartbeat-timeout-secs; default 10) |
RUSTY_GRID_REAPER_INTERVAL_SECS |
Master | Frequency of dead-worker reaper evaluation sweeps (--reaper-interval-secs; default 1) |
RUSTY_GRID_MAX_HOST_CPU_PCT |
Master | Host CPU % threshold for anti-stuttering backpressure (--max-host-cpu-pct; default 85.0) |
RUSTY_GRID_PRESERVE_GPU |
Master | Flag to preserve GPU workers for GPU-specific workloads (--preserve-gpu; default true) |
RUSTY_GRID_FAIL_UNFULFILLABLE_TASKS |
Master | Immediately fail tasks whose required capabilities or placement constraints no registered worker can satisfy (--fail-unfulfillable-tasks; default false) |
RUSTY_GRID_P2P |
Master | Enables Iroh QUIC/DERP P2P WAN endpoint (--p2p) |
RUSTY_GRID_P2P_TICKET_FILE |
Master | File path where generated P2P ticket string is written (--p2p-ticket-file) |
RUSTY_GRID_P2P_KEY_FILE |
Master | File path where master P2P identity key is persisted (--p2p-key-file) |
RUSTY_GRID_EPHEMERAL_KEY |
Master | Forces generation of ephemeral P2P key without file persistence (--ephemeral-key) |
RUSTY_GRID_RELAY_URL |
Master, Worker & Client | Custom https:// iroh relay URL for P2P endpoints (--relay-url, [master].relay_url, [worker].relay_url, [client].relay_url, [submit].relay_url, [status].relay_url; selects RelayMode::Custom on presets::Minimal and conflicts with RUSTY_GRID_P2P_MINIMAL, design 0049) |
RUSTY_GRID_P2P_MINIMAL |
Master, Worker & CLI | Selects iroh::endpoint::presets::Minimal (disabling DERP relay and pkarr/DNS address lookup) in oxideswarm master, oxideswarm worker, and client P2P connections (1, true, yes, or on), logging a startup warning (design 0030) |
RUSTY_GRID_MAX_QUEUE_SIZE |
Master | Maximum queued or running (non-terminal) tasks held in the queue (--max-queue-size; minimum 1) |
RUSTY_GRID_SCHEDULER_POLICY |
Master | Load-balancing policy (--scheduler-policy: weighted, least-loaded, or round-robin; default weighted) |
RUSTY_GRID_WIRE_CODEC |
Master, Worker & Client | Wire format serialization codec (--wire-codec: bincode or json; default bincode; invalid values exit 1) |
RUSTY_GRID_DEFAULT_RETRY_MAX |
Master | Default task retry ceiling on failure (--default-retry-max; default 3) |
RUSTY_GRID_MAX_RETRIES |
Master | Secondary alias for default task retry ceiling (--max-retries) |
RUSTY_GRID_MAX_RETAINED_TASKS |
Master | Maximum count of finished tasks retained in memory (--max-retained-tasks; default 10000) |
RUSTY_GRID_MAX_RETAINED_MB |
Master | Maximum megabytes of finished task payloads and output retained (--max-retained-mb; default 256) |
RUSTY_GRID_MAX_ACTIVE_MB |
Master & Agent Mesh | Maximum megabytes of active (non-terminal) task payloads held in the queue (--max-active-mb on oxideswarm master and agent-mesh hub; default 256, minimum 1) |
RUSTY_GRID_STATE_DIR |
Master | Directory of the durable task queue store (--state-dir, [master].state_dir; persists store.lock, snapshot.bin, and journal.bin in plaintext with mode 0700/0600 on Unix and defaults --blob-dir to <state_dir>/blobs, design 0046) |
RUSTY_GRID_SESSION_RESUME_HOLD_SECS |
Master | Seconds the master holds in-flight tasks for a reconnecting worker to adopt via ResumeSession (--session-resume-hold-secs, [master].session_resume_hold_secs; default 30, 0 disables session resume, design 0046) |
RUSTY_GRID_BLOB_DIR |
Master | Directory of the blob store of task input and output files (--blob-dir; default <state_dir>/blobs when --state-dir is set, else ~/.oxideswarm/blobs) |
RUSTY_GRID_BLOB_STORE_MB |
Master | Megabytes the blob store holds before evicting least recently used files (--blob-store-mb; default 4096) |
RUSTY_GRID_MAPREDUCE_PARALLELISM |
Master | Maximum concurrent in-flight map/reduce chunk tasks (--mapreduce-parallelism; default 256) |
RUSTY_GRID_MAX_CONNECTIONS |
Master | Maximum concurrent TCP connections allowed on grid port (--max-connections; default 1024) |
RUSTY_GRID_MAX_PENDING_HANDSHAKES |
Master | Maximum connections permitted in pre-auth handshake state (--max-pending-handshakes; default 64) |
RUSTY_GRID_INSECURE |
Master, Worker, CLI & MCP | Allows the master to bind non-loopback or a worker, client, or mcp server to connect to a remote or auto-discovered master without a cluster secret (--insecure) |
RUSTY_GRID_DASHBOARD_PORT |
Master & ox-mode |
HTTP listener port for embedded web dashboard on Master (--dashboard-port; default 8080) and target dashboard port for ox-mode dev status (--port) |
OXIDE_SWARM_DASHBOARD_PORT |
Master | Alternative alias for dashboard HTTP port |
RUSTY_GRID_DASHBOARD_PORT_FILE |
Master | File path where bound dashboard HTTP port is written (--dashboard-port-file) |
OXIDE_SWARM_DASHBOARD_PORT_FILE |
Master | Alternative alias for dashboard port file |
RUSTY_GRID_DISABLE_WEB_UI |
Master | Disables embedding of Axum web dashboard server when set |
RUSTY_GRID_ENABLE_WEB_UI |
Master | Explicit override to force-enable web dashboard server (1 or true) |
RUSTY_GRID_DISABLE_DISCOVERY |
Master | Disables UDP discovery beacon listener/broadcaster when set |
OXIDESWARM_RENDEZVOUS |
Master & Worker | HTTP rendezvous registry URL for publishing or discovering the coordinator address lease (--rendezvous) |
RUSTY_GRID_RENDEZVOUS |
Master & Worker | Secondary alias for OXIDESWARM_RENDEZVOUS |
OXIDE_DEV_MODE |
Master | Enables dashboard local development bypass on loopback interfaces (1 or true; equivalent to --dev) |
Tier C: Worker Node Engine, GPU, CUDA, Blender & 3D Subsystem
| Variable | Component | Purpose |
|---|---|---|
OXIDESWARM_MASTER |
CLI & MCP | Target Master grid address (--master HOST:PORT, auto, or an iroh P2P connection ticket) |
RUSTY_GRID_MASTER_ADDR |
Worker & CLI | Target Master grid address (--master HOST:PORT, auto, or P2P ticket) |
RUSTY_GRID_MASTER |
Worker & CLI | Secondary alias for Master grid address |
RUSTY_GRID_P2P_TICKET |
Worker | Iroh P2P connection ticket for remote NAT traversal (--p2p-ticket) |
RUSTY_GRID_WORKER_NAME |
Worker | Advertised worker name (--name; persists UUID to ~/.oxideswarm/worker_id.<NAME>) |
RUSTY_GRID_NAME |
Worker | Secondary alias for worker name |
RUSTY_GRID_WORKER_TAGS |
Worker | Comma-separated user tags advertised to the master (--tag; matched by submit --require-tag) |
RUSTY_GRID_WORKER_ID_FILE |
Worker | Explicit file path where worker node UUID is persisted |
RUSTY_GRID_CORES |
Worker | Advertised CPU core count override (--cores) |
RUSTY_GRID_CPU_CORES |
Worker | Secondary alias for advertised CPU core count (--cpu-cores) |
RUSTY_GRID_RAM_MB |
Worker | Advertised RAM in megabytes override (--ram-mb) |
RUSTY_GRID_OVERRIDE_RAM_MB |
Worker | Secondary alias for advertised RAM override (--override-ram-mb) |
RUSTY_GRID_GPU |
Worker | Insist on real GPU activation (--gpu) |
RUSTY_GRID_ENABLE_GPU |
Worker | Secondary alias to request GPU activation |
RUSTY_GRID_NO_GPU |
Worker | Forcefully suppresses GPU discovery and advertising (--no-gpu) |
RUSTY_GRID_SIMULATE_GPU |
Worker | Advertises simulated GPU executing GEMM on CPU fallback (--simulate-gpu) |
RUSTY_GRID_GPU_NAME |
Worker | Custom advertised GPU model string (--gpu-name) |
RUSTY_GRID_VRAM_MB |
Worker | Override advertised GPU VRAM in megabytes (--vram-mb) |
RUSTY_GRID_GPU_VRAM_MB |
Worker | Secondary alias for advertised GPU VRAM override |
OXIDE_SWARM_VRAM_MB |
Worker | Fallback env alias read by capability detection for GPU VRAM in megabytes |
RUSTY_GRID_CUDA |
Worker | Explicitly advertise NVIDIA CUDA support (--cuda) |
RUSTY_GRID_ENABLE_CUDA |
Worker | Secondary alias to advertise CUDA support |
OXIDE_SWARM_CUDA |
Worker | Fallback env alias read by capability detection for CUDA support |
RUSTY_GRID_NO_CUDA |
Worker | Explicitly disable CUDA support (--no-cuda) |
RUSTY_GRID_DISABLE_CUDA |
Worker | Secondary alias to disable CUDA support |
OXIDE_SWARM_NO_CUDA |
Worker | Fallback env alias read by capability detection to disable CUDA support |
CUDA_PATH / CUDA_HOME / CUDA_ROOT |
Worker | Standard NVIDIA CUDA toolkit installation directories inspected during host capability probing |
RUSTY_GRID_BLENDER |
Worker | Explicitly advertise headless Blender capability (--blender) |
RUSTY_GRID_ENABLE_BLENDER |
Worker | Secondary alias to advertise Blender capability |
RUSTY_GRID_NO_BLENDER |
Worker | Explicitly disable headless Blender capability (--no-blender) |
RUSTY_GRID_DISABLE_BLENDER |
Worker | Secondary alias to disable Blender capability |
OXIDE_SWARM_NO_BLENDER |
Worker | Fallback env alias read by capability detection to disable Blender capability |
RUSTY_GRID_BLENDER_PATH |
Worker | Explicit path to the host Blender executable (--blender-path) |
OXIDE_SWARM_BLENDER_PATH |
Worker | Secondary alias for the host Blender executable path |
BLENDER_PATH |
Worker | Standard fallback environment variable for the host Blender executable path |
RUSTY_GRID_BLENDER_VERSION |
Worker | Override advertised Blender version string (--blender-version) |
OXIDESWARM_PYTHON |
Worker (3D) | Explicit Python 3 interpreter path for Tier 1 3D generation (engines/generative_3d/entrypoint.py) |
RUSTY_GRID_PYTHON |
Worker (3D) | Secondary alias for OXIDESWARM_PYTHON |
OXIDESWARM_GEN3D_SCRIPT |
Worker (3D) | Explicit path to engines/generative_3d/entrypoint.py when the worker runs outside the repository checkout |
RUSTY_GRID_ENABLE_PHYSICAL_GPU |
Worker | Force-enables hardware wgpu engine initialization when set to 1 |
RUSTY_GRID_REQUIRE_GPU |
Worker (Tests) | In tests (1), asserts that failure to initialize a physical GPU is fatal instead of skipping |
RUSTY_GRID_REQUIRE_BLENDER |
Worker (Tests) | In tests (1 or true), asserts that a missing host Blender binary is fatal instead of skipping |
RUSTY_GRID_MAX_CONCURRENCY |
Worker | Maximum simultaneous concurrent tasks executed (--max-concurrency) |
RUSTY_GRID_MAX_CONCURRENT_TASKS |
Worker | Secondary alias for maximum concurrent tasks (--max-concurrent-tasks) |
RUSTY_GRID_SANDBOX_BASE_DIR |
Worker | Base filesystem directory for task execution sandboxes, used as given (--sandbox-base-dir outranks it). Without either, the worker uses <TMPDIR or temp dir>/rusty_grid-<euid>/sandboxes on Unix, private to its user (design 0021), and %TEMP%\rusty_grid\sandboxes on Windows |
RUSTY_GRID_ISOLATION |
Worker | Isolation level of task processes (--isolation): off, fs, or fs+net |
RUSTY_GRID_TASK_PRIORITY |
Worker | Process scheduling priority (--task-priority): normal, below-normal, or idle |
RUSTY_GRID_KEEP_SANDBOXES |
Worker | Retains task working directories upon completion (--keep-sandboxes) |
RUSTY_GRID_BLOB_CACHE_MB |
Worker | Megabytes of task input and output files cached in <sandbox base>/cache/blobs (--blob-cache-mb; default 2048) |
RUSTY_GRID_OUTPUT_LIMIT_MB |
Worker | Megabytes of output files one task may bring back; more fails the task (--output-limit-mb; default 1024) |
RUSTY_GRID_WORKSPACES |
Worker | Enables persistent named workspaces on the worker (--workspaces, [worker].workspaces; default false, design 0039) |
RUSTY_GRID_WORKSPACE_ROOT |
Worker | Root directory of the persistent workspace store (--workspace-root, [worker].workspace_root; default <cache dir>/oxideswarm/workspaces) |
RUSTY_GRID_WORKSPACE_LIMIT_MB |
Worker | Per-workspace disk quota in MiB (--workspace-limit-mb, [worker].workspace_limit_mb; default 20480) |
RUSTY_GRID_MAX_WORKSPACES |
Worker | Maximum persistent workspaces retained on disk before idle LRU eviction (--max-workspaces, [worker].max_workspaces; default 8) |
RUSTY_GRID_NO_PORTAL |
Worker | Leaves out the standby portal on :8080 (--no-portal), e.g. for a second worker on one machine |
RUSTY_GRID_NO_BATTERY |
Worker | Disables host battery and thermal probing in oxideswarm worker (1, true, yes, or on), logging a startup warning (design 0028) |
RUSTY_GRID_SESSION_RESUME_GRACE_SECS |
Worker | Optional upper bound in seconds on how long the worker keeps running tasks alive across a disconnect (--session-resume-grace-secs, [worker].session_resume_grace_secs; clamped to hold - dead_peer_timeout - 3 s, 0 disables worker session resume, design 0046) |
Tier D: Task Child Process Injection Environment
| Variable | Component | Purpose |
|---|---|---|
RUSTY_GRID_TASK_ID |
Task Runner | UUIDv4 string of the currently executing task (injected into child env) |
RUSTY_GRID_WORKER_ID |
Task Runner | UUIDv4 string of the assigned worker node |
RUSTY_GRID_SANDBOX_DIR |
Task Runner | Absolute path to the isolated scratch working directory (or the workspace tree/ directory for workspace tasks) |
RUSTY_GRID_WORKSPACE |
Task Runner | Workspace name when the task runs inside a persistent named workspace (Task::workspace) |
RUSTY_GRID_WORKSPACE_DIR |
Task Runner | Absolute path to <workspace_root>/<name>/tree when the task runs inside a persistent named workspace |
Tier E: Subnet Discovery & Network Helpers
| Variable | Component | Purpose |
|---|---|---|
OXIDESWARM_DISCOVERY_CANDIDATES |
Discovery | Comma-separated list of candidate IP addresses (IP or IP:PORT) probed during Tier 2 unicast discovery |
RUSTY_GRID_DISCOVERY_CANDIDATES |
Discovery | Secondary alias for OXIDESWARM_DISCOVERY_CANDIDATES |
OXIDESWARM_RENDEZVOUS |
Discovery | Tier 3 HTTP rendezvous registry URL for discovery fallback on isolated subnets |
RUSTY_GRID_RENDEZVOUS |
Discovery | Secondary alias for OXIDESWARM_RENDEZVOUS |
Tier F: Agent Mesh Framework
| Variable | Component | Purpose |
|---|---|---|
OXIDE_MESH_TOKEN |
Agent Mesh | Shared token authenticating agent-mesh nodes and HTTP API callers against agent-mesh hub (--token; stripped from child task environments) |
OXIDE_MESH_TLS_CA |
Agent Mesh | Path to an additional trusted CA certificate (PEM or DER) for wss:// hub connections behind a private TLS proxy (--tls-ca; proxy leaf certificate must have CA:FALSE and subjectAltName, signed by a CA:TRUE root) |
OXIDE_MESH_NO_SHELL |
Agent Mesh / Launchers | When set to 1, disables shell_exec command execution on node launchers (--no-shell) |
OXIDE_GRID_MASTER |
Agent Mesh | Bind address for the embedded Grid Master inside agent-mesh hub (--grid-master) |
Tier G: Platform Packaging, Service Automation, Agent Hub & Launchers
| Variable | Component | Purpose |
|---|---|---|
OXIDESWARM_HOME |
Global & Launchers | Custom state directory override (default: ~/.oxideswarm / %USERPROFILE%\.oxideswarm) |
OXIDESWARM_BIN |
Launchers | Explicit binary path override for shell and PowerShell launchers |
OXIDESWARM_CLUSTER_PORT |
Launchers | TCP port override used by switch_role.sh / windows\oxctl.ps1 (default: 8088) |
OXIDESWARM_DASHBOARD_PORT |
Launchers | Dashboard port override used by switch_role.sh / windows\oxctl.ps1 (default: 8080) |
OXIDESWARM_WORKER_NAME |
Launchers | Worker node name assigned by launcher automation scripts |
OXIDESWARM_CARGO_FEATURES |
Launchers | Cargo features used during automated on-demand compilation (default: gpu-wgpu) |
OXIDESWARM_P2P_TICKET |
Windows Service | Ticket storage variable used by Windows PowerShell service wrappers |
OXIDESWARM_CONFIG |
Windows Service | Machine-level config path read by packaging/windows/ServiceWrapper.cs |
OXIDESWARM_LOG_DIR |
Windows Service | Machine-level log directory read by packaging/windows/ServiceWrapper.cs |
OXIDESWARM_AGENT_HUB |
Agent Bridge | Google Drive / shared folder path for scripts/agent_bridge.py |
OXIDESWARM_AGENT_ID |
Agent Bridge | Identity of scripts/agent_bridge.py when --agent-id is not given (default: the platform, mac, win or linux); a machine sets it in .claude/settings.local.json to give the shared Claude Code hooks its own mailbox (design 0007 D5) |
OXIDESWARM_EVENT_KIND / OXIDESWARM_EVENT_FILE / OXIDESWARM_EVENT_TITLE / OXIDESWARM_EVENT_PRIORITY / OXIDESWARM_EVENT_FROM |
Agent Bridge | Event metadata variables passed to --on-event hooks by scripts/agent_bridge.py watch |
OXIDESWARM_SYNC_DIR |
Sync Probe | Base directory override for scripts/sync_network/sync_network.py |
OXIDE_ROOT |
Benchmarks | Root workspace directory override used by benchmark runners |
OX_SCRIPT_ROOT |
Test Suite | Custom script root used by test_launcher_scripts.py for regression verification |
6. Cross-Platform Coding Agent Mesh (agent-mesh)
OxideSwarm also contains an agent-to-agent communication layer (crates/agent_mesh) that lets coding agents on
Windows, macOS, Ubuntu Linux and Android (Termux / ADB) discover peers, transmit data payloads and route
structured commands. Nodes execute only 5 advertised commands (echo, ping, system_info, sha256_verify,shell_exec); shell_exec can be disabled with --no-shell. Treat the hub token like a password.
┌─────────────────────────────────┐
│ OxideRelay Hub │
│ (axum / tokio-tungstenite) │
│ Active Node Catalog │
└───────▲───────▲────────▲────────┘
│ │ │
Persistent WS │ │ WS │ Persistent WS
(outbound)│ │ │ (outbound)
▼ ▼ ▼
┌─────────────────┐ ┌───────────┐ ┌───────────────────┐
│ Node 1: Windows │ │Node 2: Mac│ │ Node 3: Android │
│ Coding Agent │ │Coding Agt │ │ Coding Agent │
└─────────────────┘ └───────────┘ └───────────────────┘
Key capabilities
- Outbound-only nodes: nodes connect out to the hub over WebSocket, so they need no inbound port (the hub host does).
- Explicit point-to-point addressing (
from: "node-1",to: "node-3"); the hub enforces thatfromis the registered node id and rejects duplicate ids. - Dual runtime: Rust binary
agent-mesh, and a dependency-light Python clientscripts/agent_node.py. - Delivery tracking & integrity: correlation ids,
DeliveryAck/DeliveryNack, SHA-256 verification of data payloads. - Authentication: the hub listens on
127.0.0.1:8088by default; a non-loopback--listenneeds--token(orOXIDE_MESH_TOKEN), or--insecure.ws://is not encrypted, so usewss://behind a TLS proxy or a VPN / SSH tunnel, and never expose the hub to the Internet.
Quickstart
# 1. Build the Agent Mesh CLI:
cargo build --release -p agent_mesh
# 2. Pick a hub token and start the hub. The hub also defaults to port 8088, which the grid master uses,
# so give it another port when both run on one machine:
export OXIDE_MESH_TOKEN="$(openssl rand -hex 24)"
./target/release/agent-mesh hub --listen 127.0.0.1:8090 # loopback; use 0.0.0.0:8090 + token for a LAN
# 3. Connect an agent node (Windows / Mac / Linux / Android); every command below reads OXIDE_MESH_TOKEN:
./target/release/agent-mesh node --hub ws://127.0.0.1:8090/ws --id node-mac-1 --platform macos
python3 scripts/agent_node.py --hub ws://127.0.0.1:8090/ws --id node-android-3 --platform android
# To disable shell command execution on untrusted nodes, add --no-shell:
./target/release/agent-mesh node --hub ws://127.0.0.1:8090/ws --id node-mac-1 --platform macos --no-shell
# 4. Route a command from any node or terminal:
./target/release/agent-mesh send --hub ws://127.0.0.1:8090/ws --to node-android-3 --command shell_exec --args '{"cmd": "uname -m"}'
# 5. Query the online nodes catalog:
./target/release/agent-mesh list --hub ws://127.0.0.1:8090/ws
Master Grid Runtime Integration (--grid-master)
--grid-master [ADDR] makes the hub start its own embedded Master Grid coordinator on ADDR. It does not connect
to a master that is already running, so give it a free port. A non-loopback ADDR needs a cluster secret
(--secret / OXIDESWARM_SECRET, else the default ~/.oxideswarm/cluster.secret) or an explicit --insecure:
the hub refuses to start an unauthenticated master that the network can reach. Pass --max-active-mb <MB> (or setRUSTY_GRID_MAX_ACTIVE_MB) to configure the embedded master's active queue byte budget (default 256 MiB, minimum 1 MiB).
# Start the hub with an embedded master on 127.0.0.1:9088 (loopback, so no secret is needed):
./target/release/agent-mesh hub --listen 127.0.0.1:8090 --grid-master 127.0.0.1:9088 --max-active-mb 512
# When --grid-master is configured, agent mesh nodes can dispatch compute envelopes:
# grid_compute, grid_compile, grid_submit, and grid_status execute end-to-end against the grid.
# When --grid-master is omitted, grid envelopes return ERR_BRIDGE_NOT_CONFIGURED.
Platform guides: DEPLOYMENT.md.
7. Workspace Crate Architecture
OxideSwarm/
├── Cargo.toml # Workspace root manifest (no root package)
├── README.md # This file
├── CLAUDE.md # Architecture map for AI coding assistants
├── docs/ # README.md (index + writing standard), SECURITY.md (threat model),
│ # guides/ (runbooks), design/ (design records)
├── DEPLOYMENT.md # Agent Mesh deployment guide
├── ANDROID_ARCHITECTURE.md # Android architecture (parts are design only, marked as such)
├── switch_role.sh # Master <-> Worker role switcher for macOS / Linux
├── connect_remote.sh # P2P WAN pairing for macOS / Linux
├── connect_remote.cmd # P2P WAN pairing for Windows
├── test_integration.sh # E2E: 1 master + 3 workers on loopback, private HOME
├── run_chaos_test.sh # local failover test (kills a worker that holds running tasks)
├── run_cluster_benchmark.sh # two-node benchmark (two local workers, or a phone via adb)
├── ox-mode -> scripts/mode.sh # Unified CLI & TUI workflow automation runner
├── windows/ # Windows launchers (oxctl.ps1 engine + .cmd/.vbs wrappers)
├── assets/ # Vector branding assets
├── benchmarks/interconnect/ # Interconnect comparison: static recorded data + a validator script
├── engines/
│ ├── generative_3d/ # Tier-1 3D generation Python entrypoint (`entrypoint.py`)
│ └── autorig/ # Headless Blender 4.5 LTS auto-rigging driver (`blender_rig.py`)
├── scripts/
│ ├── sync_network/ # Shared-folder reachability probe (not part of the grid)
│ ├── agent_node.py # Lightweight Python agent node client
│ └── mode.sh # Workflow mode automation script
├── packaging/
│ ├── agent_mesh/ # Agent node launchers (windows / macos / ubuntu / android)
│ ├── windows/ # Windows service: ServiceWrapper.cs (csc.exe) or WinSW, installer, verifier
│ ├── android/ # Android app project, Termux worker daemon, JNI build script
│ └── macos/ # LaunchDaemon installer / verifier / uninstaller
├── crates/
│ ├── core/ # [Layer 1] Wire protocol, codec, cluster_auth (secret handshake), discovery, workflow modes
│ ├── master/ # [Layer 1] Scheduler, GPU routing, FSM, LRU bounding, Axum dashboard, RBAC auth
│ ├── worker/ # [Layer 1] Task runner, process-tree kill, CPU SIMD / wgpu compute, gen3d, autorig, standby portal
│ ├── cli/ # [Layer 1] `oxideswarm` / `rusty-grid` / `ox-mode`; connect.rs (client plumbing), secret_cmd.rs
│ ├── android_bridge/ # [Layer 2] JNI bridge (liboxideworker.so)
│ └── agent_mesh/ # [Layer 3] Axum WebSocket relay hub & agent client
└── tests/ # Integration tests (registered per crate in Cargo.toml) and Python suites
Generative 3D & Auto-Rigging Subsystem (crates/worker/src/gen3d, crates/worker/src/autorig, engines/)
The worker executes two 3D asset pipeline task types (architecture and limits in docs/design/0023-generative-3d-and-autorig-subsystem.md, 0015, and 0017):
| Subsystem | Task Spec & CLI | Execution Tiers & Drivers | Current Limits (docs/BACKLOG.md) |
|---|---|---|---|
Generative 3D (crates/worker/src/gen3d) |
TaskSpec::Generative3D(Generative3DSpec) via oxideswarm submit --type 3d --prompt <TEXT> [--quality fast|standard|high] [--engine auto|sdf|triposr] [-o <OUT.glb>] |
Tier 0 (sdf, auto): in-process pure-Rust analytical SDF Marching Cubes (32³/48³/64³), manifold topology repair, conformal box UV unwrapping, barycentric PBR albedo PNG baking, and binary glTF 2.0 (.glb) export on CPU (device_name = "Procedural-SDF-PureRust", no GPU required).Tier 1 ( triposr stub, 3D-1): supervised Python subprocess running engines/generative_3d/entrypoint.py (located via OXIDESWARM_GEN3D_SCRIPT or relative to the worker working directory, using OXIDESWARM_PYTHON / RUSTY_GRID_PYTHON / .venv). |
Partial (3D-1, 3D-2, 3D-3): Tier 0 maps prompt keywords (robot/mech/droid/cyber/armor, chibi/cute/mascot/creature/stylized, orb/sphere/math/test, else humanoid) to four fixed analytical SDF presets (SdfPreset), rejects --image input, and takes no timeout or cancel (Planned under 3D-3). engines/generative_3d/entrypoint.py is a stub with no model code that exits 1 unconditionally (Planned under 3D-1); --engine trellis is refused upfront. required_vram_mb in crates/master/src/scheduler.rs has no caller and crates/master never reads vram_mb (Planned under 3D-2). |
Auto-Rigging & Animation (crates/worker/src/autorig) |
TaskSpec::AutoRig(AutoRigSpec) via oxideswarm submit --type autorig --input-mesh <MESH.glb|.obj> [--rig-preset biped|quadruped|generic] [--embed-animations idle,walk,turnaround] [--preferred-provider builtin|blender] [-o <OUT.glb>] |
Built-in (builtin): in-process pure-Rust .glb/.obj loader, 3×3 PCA symmetry and 50-slab 15-landmark extraction, 15-joint biped topological DAG armature + 4×4 Inverse Bind Matrices, geodesic surface skinning with sagittal barrier and top-4 weight normalization, procedural TRS keyframe synthesis (idle, walk, turnaround), and rigged .glb export.Headless Blender ( blender): supervised Blender subprocess (--blender-path / RUSTY_GRID_BLENDER_PATH) running engines/autorig/blender_rig.py (on-disk or embedded via include_str!), falling back to the built-in Rust engine if Blender is absent or fails. |
Partial (3D-2, 3D-3, Planned): Under 3D-2 (Planned), crates/master never reads has_blender, so a --preferred-provider blender task can land on a worker without Blender, and --blender-path reaches only the capability probe while resolve_blender_binary misses the macOS/Linux paths detect_blender searches. Under 3D-3 (Planned): extract_landmarks ignores _preset, build_standard_armature always builds the same 15-joint biped skeleton, and blender_rig.py parses --preset without reading it; turnaround produces an empty action in Blender; Blender input is always written as input_mesh.glb so .obj input through Blender fails; Blender uses a fixed 60 s timeout instead of the task timeout (and no task cancel), while built-in rigging takes no timeout or cancel; and a Blender failure falls back to the built-in rigger with only a warn! and the same "OxideSwarm-AutoRig" device label. |
8. Verification & Benchmarks
A full cargo test --workspace executes 800+ unit, integration, and stress tests across the workspace. Note that tests requiring public Iroh relays depend on outbound Internet connectivity to DERP relays.
# Rust unit and integration tests (slow: many stress tests)
cargo test --workspace
# Agent Mesh against the RUST hub (build first with: cargo build -p agent_mesh)
cargo test -p agent_mesh
python3 tests/test_agent_mesh_token_auth.py
python3 tests/test_agent_mesh_rust_hub_cross_interop.py
# Protocol simulation against a PYTHON reference hub (tests/run_mesh_simulation_tests.py does NOT start the Rust hub)
python3 tests/run_mesh_simulation_tests.py
# Launcher / installer scripts (switch_role.sh, connect_remote.sh, Termux supervisor, macOS installer dry-run,
# line endings, no hard-coded owner values): runs them against fake binaries in a private HOME; no build needed
python3 tests/test_launcher_scripts.py
# End-to-end on loopback: 1 master + 3 workers, one simulated-GPU worker. Uses a private HOME and
# ephemeral ports, touches no running master/worker and only signals the PIDs it started.
./test_integration.sh
# Failover: starts its own cluster, SIGKILLs a worker that holds running tasks, checks re-execution
./run_chaos_test.sh
# Throughput of two nodes (two local worker processes by default; --adb-id SERIAL uses a phone)
./run_cluster_benchmark.sh
# Static comparison data check + two local Rust benches (does NOT measure Tailscale or Cloudflare)
./benchmarks/interconnect/run_comparative_benchmark.sh
The scripts exit non-zero and say FAIL when a check fails; their reports are computed from what was observed in
that run.
Benchmarks. benchmarks/grid measures no-op task overhead with 1 to 4 workers and a first versus a repeated upload of the same input tree on loopback, with the script that produced each dated record in benchmarks/grid/results. The records state their machine, load and limits.
9. License
OxideSwarm is dual-licensed under:
- Apache License, Version 2.0 (LICENSE-APACHE)
- MIT License (LICENSE-MIT)
You may choose either license at your option.
Reviews (0)
Sign in to leave a review.
Leave a reviewNo results found