
Remote Compilation Helper Setup
- 1 installs
- 55 repo stars
- Updated August 4, 2026
- dicklesworthstone/remote_compilation_helper
Configures RCH remote build workers, installs the hook, and fixes SSH/daemon issues so cargo, bun, and gcc builds run on remote machines.
About
Sets up RCH remote compilation: prerequisites, workers.toml config, hook install, daemon start, and rch doctor validation. A developer uses it when setting up remote compilation, adding build machines, or troubleshooting no-workers-available errors.
- Setup checklist with workers.toml config schema
- rch doctor --fix flow and SSH/daemon quick-fix table
Remote Compilation Helper Setup by the numbers
- 1 all-time installs (skills.sh)
- Ranked #1,173 of 1,435 DevOps & CI/CD skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/dicklesworthstone/remote_compilation_helper --skill remote-compilation-helper-setupAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 1 |
|---|---|
| repo stars | ★ 55 |
| Last updated | August 4, 2026 |
| Repository | dicklesworthstone/remote_compilation_helper ↗ |
What it does
Configures RCH remote build workers, installs the hook, and fixes SSH/daemon issues so cargo, bun, and gcc builds run on remote machines.
Files
RCH Setup
Offloads cargo build, bun test, gcc to remote workers. Transparent—same commands, faster builds.
Workflow
1. rch doctor # What's broken?
2. rch doctor --fix # Auto-fix common issues
3. rch doctor # All green? Done.If --fix can't solve it, continue below.
Setup Checklist
- [ ] Prerequisites:
which rustup rsync zstd(install missing) - [ ] Install:
cargo install --path rch(or--path .from repo root) - [ ] Configure: Create
~/.config/rch/workers.toml(see below) - [ ] Hook:
rch hook install - [ ] Daemon:
rchd &orsystemctl --user start rchd - [ ] Validate:
rch doctor→ all checks pass
Worker Config
# ~/.config/rch/workers.toml
[[workers]]
id = "worker1"
host = "192.168.1.100"
user = "ubuntu"
identity_file = "~/.ssh/id_ed25519"
total_slots = 8 # ≈ CPU cores - 2
priority = 100 # Higher = preferred
tags = ["rust"] # Optional capability tagsDiscover from SSH config:
rch workers discover --from-ssh-config --dry-run # Preview
rch workers discover --from-ssh-config # Add to configVerify workers:
rch workers probe worker1 --verbose # Test single
rch workers probe --all # Test all
rch workers list --capabilities # Show detected toolchainsQuick Fixes
| Symptom | Fix |
|---|---|
| SSH fails | eval $(ssh-agent) && ssh-add ~/.ssh/your_key |
| Daemon down | rm -f /tmp/rch.sock && rchd & |
| Hook missing | rch hook install --force |
| No workers | Check config path, SSH connectivity |
Test hook directly:
echo '{"tool":"Bash","input":{"command":"cargo check"}}' | rch hook
# Expect: {"allow":true,"output":"..."}Validation
rch doctor --verbose # Full diagnostics
rch doctor --json # Machine-readable
RCH_DRY_RUN=1 cargo check # Test without remote execution⚠️ All `rch doctor` checks must pass before use.
References
| Topic | Reference |
|---|---|
| Worker schema, selection algorithm, tags | WORKERS.md |
| All error messages & detailed fixes | TROUBLESHOOTING.md |
| Hook protocol, 5-tier classification | HOOKS.md |
# RCH Workers Configuration Template
# Copy to: ~/.config/rch/workers.toml
#
# Each [[workers]] block defines a remote machine for compilation offloading.
# RCH selects workers based on available slots, priority, and project locality.
# Example: Primary fast build server
[[workers]]
id = "primary" # Unique identifier
host = "192.168.1.100" # IP or hostname
user = "ubuntu" # SSH username
identity_file = "~/.ssh/id_ed25519" # Path to SSH private key
total_slots = 16 # Max concurrent jobs (usually CPU cores)
priority = 100 # Higher = preferred (default: 50)
tags = ["rust", "bun", "fast"] # Optional capability tags
# enabled = true # Set to false to disable temporarily
# Example: Secondary backup server (lower priority)
# [[workers]]
# id = "backup"
# host = "build-backup.local"
# user = "build"
# identity_file = "~/.ssh/build_key"
# total_slots = 8
# priority = 50
# tags = ["rust"]
# Example: Specialized TypeScript worker
# [[workers]]
# id = "typescript-builder"
# host = "ts.internal"
# user = "node"
# identity_file = "~/.ssh/ts_key"
# total_slots = 12
# priority = 75
# tags = ["bun", "typescript"]
# Tips:
# - total_slots: Match to CPU cores. Leave 1-2 for system overhead.
# - priority: Range 1-100. Equal slots? Higher priority wins.
# - tags: Projects can require specific tags in .rch.toml
# - identity_file: Use ssh-agent for passphrase-protected keys
#
# Test your configuration:
# rch config check
# rch workers probe --all
Hook Integration
Flow
Claude Code → PreToolUse Hook → rch
│
┌────────────┴────────────┐
│ Bash tool? │
│ └─ Compilation cmd? │
│ └─ Yes → Remote │
│ └─ No → Local │
│ └─ No → Pass through │
└─────────────────────────┘Installation
rch hook install # Modifies ~/.claude/settings.json
rch hook status # Verify
rch hook uninstall # RemoveAdds to settings:
{"hooks":{"PreToolUse":[{"matcher":"Bash","command":"/path/to/rch hook"}]}}Protocol
Input (stdin):
{"tool":"Bash","input":{"command":"cargo build --release"}}Output (stdout):
| Response | JSON | Meaning |
|---|---|---|
| Pass through | {"allow":true} | Run locally |
| Intercept | {"allow":true,"output":"..."} | Return captured output |
| Block | {"allow":false,"reason":"..."} | Prevent execution |
Classification (5-tier, <5ms total)
| Tier | Time | Check |
|---|---|---|
| 1 | <100μs | Keyword bloom filter |
| 2 | <200μs | Quick regex scan |
| 3 | <500μs | Full command parse |
| 4 | <1ms | Context extraction |
| 5 | <5ms | Worker selection |
Intercepted
cargo build/test/check/run, rustc
bun test, bun typecheck
gcc, g++, clang, clang++, cc
make, cmake --build, ninja, meson compileNever Intercepted
bun install/add/remove # Modifies node_modules
bun run/dev/build # Needs local ports
cargo build | tee log # Piped
cargo build > output.txt # Redirected
cargo build & # BackgroundTesting
# Test classification
echo '{"tool":"Bash","input":{"command":"cargo build"}}' | rch hook
# → {"allow":true,"output":"..."}
echo '{"tool":"Bash","input":{"command":"ls -la"}}' | rch hook
# → {"allow":true}
# Dry run with file input
RCH_DRY_RUN=1 rch hook < test-input.json
# Dry run (logs but no remote execution)
RCH_DRY_RUN=1 cargo check
# Debug logging
RCH_LOG=debug cargo build
RCH_LOG=trace cargo build # Maximum detail
# Verify hook is running
ps aux | grep rchConfiguration
~/.config/rch/config.toml:
[hook]
classify_timeout_ms = 5 # Classification budget
pipeline_timeout_s = 300 # Full pipeline timeout
fail_open = true # On error → allow local execution
local_patterns = [ # Force local execution
"cargo fmt",
"cargo doc"
]Uninstalling
rch hook uninstall # Removes hook from ~/.claude/settings.json
# Manual removal: edit ~/.claude/settings.json and remove the PreToolUse entrySecurity
- Runs with user permissions
- SSH keys via ssh-agent (recommended)
- Workers should be trusted machines
- Never modifies source code
- Artifacts transferred via secure rsync
Troubleshooting
First step: rch doctor --verbose
Symptom Index
| Error Message | Jump To |
|---|---|
| "Permission denied (publickey)" | SSH Issues |
| "Connection refused" | SSH Issues |
| "Host key verification failed" | SSH Issues |
| "No config file" / "Config not found" | Configuration |
| "Invalid TOML" | Configuration |
| "Daemon not running" / socket errors | Daemon |
| "Hook not triggering" | Hook Issues |
| "No workers available" | Worker Issues |
| "Transfer failed" | Worker Issues |
| Compilation slower than local | Performance |
---
Installation
# Rust nightly not installed
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
rustup install nightly && rustup default nightly
# Edition 2024 error → need recent nightly
rustup update nightly
rustc +nightly --version # Need 1.82+
# Missing rsync/zstd
sudo apt install rsync zstd # Debian/Ubuntu
brew install rsync zstd # macOS
sudo dnf install rsync zstd # Fedora---
SSH Issues
| Symptom | Diagnose | Fix |
|---|---|---|
| Permission denied | ssh -vvv -i key user@host | chmod 600 ~/.ssh/*; check key path |
| Connection refused | nc -zv host 22 | Check firewall (ssh worker "sudo ufw status"), SSH service |
| Host key failed | — | ssh-keyscan host >> ~/.ssh/known_hosts |
| Agent not running | echo $SSH_AUTH_SOCK | eval $(ssh-agent) && ssh-add |
| Key not found | ls -la ~/.ssh/ | Verify key file exists at configured path |
Full SSH debug: ssh -vvv -i ~/.ssh/key user@host "echo ok"
---
Configuration
# No config directory
mkdir -p ~/.config/rch
# Create minimal config
cat > ~/.config/rch/workers.toml << 'EOF'
[[workers]]
id = "worker1"
host = "192.168.1.100"
user = "ubuntu"
identity_file = "~/.ssh/id_ed25519"
total_slots = 8
priority = 100
EOF
# Or use interactive wizard
rch init
# Validate syntax
rch config checkCommon TOML mistakes:
- Missing quotes around string values
[workers]instead of[[workers]]- Typos in field names
---
Daemon
| Symptom | Check | Fix |
|---|---|---|
| Not running | pgrep rchd | rchd & or systemctl --user start rchd |
| Socket missing | ls /tmp/rch.sock | Start daemon |
| Socket stale | Socket exists but daemon dead | rm /tmp/rch.sock && rchd |
| Permission denied | ls -la /tmp/rch.sock | Check socket permissions |
| Crashes | rchd --foreground --verbose | Check logs for error |
Daemon logs: journalctl --user -u rchd -f
Deep debug: rchd --foreground --log-level=debug
---
Hook Issues
| Symptom | Check | Fix |
|---|---|---|
| Not registered | `cat ~/.claude/settings.json \ | jq '.hooks.PreToolUse'` |
| Binary not found | which rch | Ensure rch is in PATH |
| Returns error | `echo '{"tool":"Bash","input":{"command":"cargo check"}}' \ | rch hook` |
| Not intercepting | rch classify "cargo build" | Verify command is supported |
Commands never intercepted (by design):
bun install/add/remove(package management)bun run/dev/build(local execution)- Piped:
cargo build | tee log - Background:
cargo build &
Test hook directly:
echo '{"tool":"Bash","input":{"command":"cargo build"}}' | rch hook
# Expect: {"allow":true,"output":"..."}
RCH_DRY_RUN=1 cargo check # Logs decision without remote execution---
Worker Issues
| Symptom | Check | Fix |
|---|---|---|
| No workers | rch workers status | Add workers to config |
| No slots | rch workers list --verbose | Wait or add more workers |
| Can't connect | ssh -i key user@host "echo ok" | Fix SSH (see above) |
| Missing toolchain | ssh worker "which rustc bun" | Install on worker |
| Transfer fails | rsync -avz --dry-run ./src/ worker:/tmp/t/ | Check disk space, rsync version |
Install Rust on worker: ssh worker "curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh"
Check worker disk: ssh worker "df -h /tmp"
Check rsync compatibility: rsync --version and ssh worker "rsync --version"
---
Performance
| Symptom | Likely Cause | Fix |
|---|---|---|
| Slower than local | Project too small (<2s compile) | RCH overhead ~100-500ms; only helps for longer builds |
| High transfer time | Large project / slow network | Check .rchignore excludes target/, node_modules/ |
| Worker slow | High load | `ssh worker "uptime; top -bn1 \ |
Profile transfer: time rsync -avz ./src/ worker:/tmp/test/
Check network: ping -c 5 worker
Debug transfer: RCH_LOG=debug cargo build 2>&1 | grep transfer
---
Debug Mode
export RCH_LOG=debug # or trace for maximum detail
cargo build # Logs show hook decisions
# Levels: error, warn, info, debug, trace---
Getting Help
rch --version # Show version
rch --help # General help
rch doctor --help # Doctor subcommand help
rch workers --help # Workers subcommand helpGenerate Diagnostic Report
rch doctor --json > diagnostic.jsonWorker Configuration
Schema
[[workers]]
id = "unique-name" # Required
host = "192.168.1.100" # Required: IP or hostname
user = "ubuntu" # Required: SSH user
identity_file = "~/.ssh/key" # Required: SSH key path
total_slots = 16 # Required: max concurrent jobs (≈ CPU cores - 2)
priority = 100 # Optional: selection weight (default: 50, higher = preferred)
tags = ["rust", "fast"] # Optional: capability tags
enabled = true # Optional: set false to disable (default: true)Selection Algorithm
score = available_slots × priority × locality_bonus1. Available slots: total_slots - active_jobs 2. Priority: tiebreaker when slots equal 3. Locality: bonus for workers with cached project data 4. Tags: project can require specific tags via .rch.toml
Multi-Worker Example
# Primary (fast, high priority)
[[workers]]
id = "fast-builder"
host = "build-server.local"
user = "build"
identity_file = "~/.ssh/build_key"
total_slots = 48
priority = 100
tags = ["fast", "rust", "bun"]
# Secondary (fallback when primary busy)
[[workers]]
id = "backup"
host = "192.168.1.50"
user = "ubuntu"
identity_file = "~/.ssh/id_ed25519"
total_slots = 8
priority = 50
tags = ["rust"]
# Specialized TypeScript worker
[[workers]]
id = "ts-builder"
host = "ts.internal"
user = "node"
identity_file = "~/.ssh/ts_key"
total_slots = 16
priority = 75
tags = ["bun", "typescript"]SSH Config Discovery
rch workers discover --from-ssh-config --dry-run # Preview
rch workers discover --from-ssh-config # Add to config
rch workers discover --from-ssh-config --filter "build*" # Filter by patternRequired SSH config fields: Host, HostName, User, IdentityFile
Optional RCH hints (in SSH config comments):
Host build-server
HostName 192.168.1.100
User ubuntu
IdentityFile ~/.ssh/build_key
# rch-slots: 16
# rch-priority: 90
# rch-tags: rust,bunProbing & Monitoring
rch workers probe worker1 --verbose # Test connectivity + detect toolchains
rch workers probe --all # Probe all workers
rch workers status # Current state
rch workers status --json # For monitoring tools
watch -n 5 'rch workers status' # Continuous monitoringProbe output shows: SSH connectivity, detected toolchains (rustc, cargo, bun, gcc), disk space, load.
Tags
Workers declare capabilities:
[[workers]]
id = "polyglot"
tags = ["rust", "bun", "cpp"]Projects require tags:
# .rch.toml in project root
required_tags = ["rust", "fast"]Slot Sizing
ssh worker1 "nproc" # Check cores
# Rule: total_slots = cores - 2 (leave headroom for system)Disable/Enable
[[workers]]
id = "under-maintenance"
enabled = false # Won't be selected#!/usr/bin/env bash
# RCH Setup Validation Script
# Checks that RCH is properly configured and ready to use
set -euo pipefail
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
ERRORS=0
WARNINGS=0
pass() { echo -e "${GREEN}[PASS]${NC} $1"; }
fail() { echo -e "${RED}[FAIL]${NC} $1"; ((ERRORS++)); }
warn() { echo -e "${YELLOW}[WARN]${NC} $1"; ((WARNINGS++)); }
info() { echo -e " $1"; }
echo "RCH Setup Validation"
echo "===================="
echo
# 1. Check prerequisites
echo "Prerequisites:"
if command -v rch &>/dev/null; then
pass "rch binary found: $(which rch)"
else
fail "rch binary not found in PATH"
fi
if command -v rsync &>/dev/null; then
pass "rsync installed"
else
fail "rsync not installed"
fi
if command -v zstd &>/dev/null; then
pass "zstd installed"
else
fail "zstd not installed"
fi
if [ -n "${SSH_AUTH_SOCK:-}" ]; then
pass "ssh-agent running"
else
warn "ssh-agent not running (may need: eval \$(ssh-agent) && ssh-add)"
fi
echo
# 2. Check configuration
echo "Configuration:"
CONFIG_DIR="${XDG_CONFIG_HOME:-$HOME/.config}/rch"
WORKERS_FILE="$CONFIG_DIR/workers.toml"
if [ -d "$CONFIG_DIR" ]; then
pass "Config directory exists: $CONFIG_DIR"
else
fail "Config directory missing: $CONFIG_DIR"
fi
if [ -f "$WORKERS_FILE" ]; then
pass "Workers config exists: $WORKERS_FILE"
# Count workers
WORKER_COUNT=$(grep -c '^\[\[workers\]\]' "$WORKERS_FILE" 2>/dev/null || echo 0)
if [ "$WORKER_COUNT" -gt 0 ]; then
pass "Found $WORKER_COUNT worker(s) configured"
else
fail "No workers defined in $WORKERS_FILE"
fi
else
fail "Workers config missing: $WORKERS_FILE"
fi
echo
# 3. Check daemon
echo "Daemon:"
SOCKET_PATH="/tmp/rch.sock"
if [ -S "$SOCKET_PATH" ]; then
pass "Daemon socket exists: $SOCKET_PATH"
else
warn "Daemon socket not found (rchd may not be running)"
fi
if pgrep -x rchd &>/dev/null; then
pass "rchd process running"
else
warn "rchd not running (start with: rchd &)"
fi
echo
# 4. Check Claude Code hook
echo "Claude Code Hook:"
SETTINGS_FILE="$HOME/.claude/settings.json"
if [ -f "$SETTINGS_FILE" ]; then
if grep -q "PreToolUse" "$SETTINGS_FILE" 2>/dev/null; then
if grep -q "rch" "$SETTINGS_FILE" 2>/dev/null; then
pass "RCH hook registered in Claude Code"
else
fail "PreToolUse exists but RCH not configured"
fi
else
fail "No PreToolUse hook configured"
fi
else
fail "Claude Code settings not found: $SETTINGS_FILE"
fi
echo
# 5. Summary
echo "===================="
if [ $ERRORS -eq 0 ] && [ $WARNINGS -eq 0 ]; then
echo -e "${GREEN}All checks passed! RCH is ready.${NC}"
exit 0
elif [ $ERRORS -eq 0 ]; then
echo -e "${YELLOW}$WARNINGS warning(s), no errors. RCH may work with limitations.${NC}"
exit 0
else
echo -e "${RED}$ERRORS error(s), $WARNINGS warning(s). Run 'rch doctor --fix' to resolve.${NC}"
exit 1
fi