A Road Warrior’s Guide to Verification on the Move Running a DamageBDD Node on an Android Phone — the Arch Way A verification node should not need a rack, a permanent office or permission from a cloud provider. An Android phone already contains the essentials: an ARM processor, storage, radios, a battery and a Linux kernel. Add Termux as the launcher, Arch Linux ARM as the userland and Erlang/OTP as the runtime, and the phone becomes a portable verification machine. Android kernel └── Termux └── PRoot-Distro └── Arch Linux ARM └── Erlang/OTP └── DamageBDD road node PRoot-Distro provides a rootless, chroot-like Linux environment without replacing Android or requiring a custom kernel. It shares the phone’s kernel and network stack rather than running a conventional virtual machine. This is not a phone pretending to be a data centre. It is a verifier that can travel. --- 1. Know the mission A road node is well suited to: - API and HTTP behaviour verification - scheduled functional checks - proof-producing test runs - testing services over Wi-Fi or mobile data - verifying infrastructure while travelling - acting as an independent node outside the cloud perimeter - collecting evidence at the point where failure is observed It is not the ideal device for sustained browser farms, CUDA workloads or high-volume load generation. PRoot intercepts system calls in userspace, while Android controls background execution, thermals and battery policy. Treat the phone as an independent edge verifier—not a planetary load generator. --- 2. Install Termux correctly Install Termux from F-Droid or the official Termux GitHub release channel. Keep Termux and its add-ons, including Termux:Boot, from the same source because their signing keys must match. Disable Android battery optimisation for Termux. Open Termux and prepare the host: pkg update pkg upgrade -y pkg install -y \ proot-distro \ git \ curl \ openssh \ tmux termux-setup-storage termux-wake-lock uname -m The preferred result is: aarch64 A 64-bit ARM phone gives the cleanest path to Arch Linux ARM and Erlang/OTP. --- 3. Install Arch Linux ARM Modern PRoot-Distro releases install distributions from OCI container images. Pin the image tag rather than relying on "latest", so that another road node can reproduce the same base system. The Arch Linux ARM image below is among the images recommended by the current PRoot-Distro project; "20260712" is a currently published pinned tag. From Termux: proot-distro install \ danhunsaker/archlinuxarm:20260712 \ --name damage-arch Enter the new system with a fully qualified hostname: proot-distro login \ --hostname damage-phone.local \ damage-arch The hostname matters because the current Damage application starts its distributed Erlang node using long names derived from the hostname. PRoot-Distro normally reports "localhost", but it supports overriding the guest hostname. You are now inside Arch. --- 4. Prepare the Arch environment Update the system and install the build chain: pacman -Syu --noconfirm pacman -S --needed --noconfirm \ base-devel \ git \ erlang \ rebar3 \ openssl \ libsodium \ gmp \ curl \ jq \ tmux Arch Linux ARM currently provides native AArch64 Erlang packages, while Rebar3 is architecture-independent. Create an isolated node user and its writable directories: useradd -m -s /bin/bash damage 2>/dev/null || true install -d -o damage -g damage /var/lib/damage install -d -o damage -g damage /var/log/damage install -d -o damage -g damage /home/damage/.local/share/damage install -d -o damage -g damage /home/damage/.local/state/damage Switch users: su - damage --- 5. Fetch DamageBDD Clone the source: git clone --depth 1 \ --branch develop \ cd DamageBDD Check the toolchain: erl -noshell \ -eval 'io:format("OTP ~s~n", [erlang:system_info(otp_release)]), halt().' rebar3 version The public DamageBDD instructions currently describe the source path as cloning the repository and running "rebar3 shell". --- 6. The important mobile reality The public server build is not yet a clean Android one-liner. The current repository configuration includes: - a CPU ECAI NIF using GMP and OpenSSL - a CUDA ECAI GPU NIF built with "nvcc" - the graphical ERM application - ECAI, Nosternity and BoP applications in the default shell - optional ChromeDriver and IPFS sidecars - server-oriented paths under "/var/lib/damage" and "/var/log/damage" - comparatively large worker pools These assumptions are reasonable for a workstation or permanent node but unnecessarily heavy for an Android road node. Before presenting Android as a supported target, DamageBDD should include a checked-in "mobile" profile with the following contract: Architecture: AArch64 Runtime: CPU only Primary app: damage Listen address: 127.0.0.1 HTTP port: 4888 GPU NIF: disabled ERM GUI: disabled ChromeDriver: disabled IPFS sidecar: disabled by default SSH listeners: disabled by default Worker pools: reduced Data directory: ~/.local/share/damage Log directory: ~/.local/state/damage Secrets: private guest storage only The Damage OTP application itself only declares its core server dependencies and Vanillae; the additional applications are being started by the top-level development shell configuration rather than being mandatory Damage application dependencies. --- 7. Create the road configuration Begin from the supplied sample: cp config/sys.config.sample config/mobile.config mkdir -p \ "$HOME/.local/share/damage" \ "$HOME/.local/state/damage" Edit "config/mobile.config" and apply these changes. Node paths {feature_dirs, ["/home/damage/DamageBDD/features/"]}, {run_user, "damage"}, {data_dir, "/home/damage/.local/share/damage/"}, Change logger paths from: /var/log/damage/ to: /home/damage/.local/state/damage/ Network binding Keep the node private by default: {ip, {127, 0, 0, 1}}, {port, 4888}, Disable sidecars Replace the configured "abduco_workers" list with: {abduco_workers, []}, Disable embedded SSH listeners {ssh_git, [ {enabled, false}, {listen_addr, {127, 0, 0, 1}}, {port, 2222}, {system_dir, "/home/damage/.local/share/damage/ssh/git/system"}, {user_dir, "/home/damage/.local/share/damage/ssh/git/user"}, {repos_root, "/home/damage/.local/share/damage/git"} ]}, {ssh_tunnel, [ {enabled, false}, {ip, {127, 0, 0, 1}}, {port, 2223}, {system_dir, "/home/damage/.local/share/damage/ssh/tunnel/system"}, {user_dir, "/home/damage/.local/share/damage/ssh/tunnel/user"} ]}, Reduce mobile worker pools Start conservatively: {pools, [ {damage, [{size, 2}, {max_overflow, 4}], []}, {damage_ai, [{size, 1}, {max_overflow, 1}], []}, {formatter, [{size, 1}, {max_overflow, 4}], []} ]}, Increase these only after observing memory use and temperature on the actual phone. --- 8. Create the CPU-only build profile The current top-level build attempts to compile the Linux CUDA NIF because its port specification matches Linux generally. For an Android phone without CUDA, copy the build configuration and remove the "apps/ecai/priv/ecai_gpu.so" port specification from the mobile copy. cp rebar.config rebar.mobile.config In "rebar.mobile.config": 1. Remove the port specification whose output is: apps/ecai/priv/ecai_gpu.so 2. Keep the CPU NIF: apps/ecai/priv/ecai.so 3. Change the shell application list so it does not automatically start the graphical and auxiliary applications: {shell, [ {config, "config/mobile.config"}, {apps, [damage]} ]}. Use the alternate configuration through "REBAR_CONFIG", which is an officially supported Rebar3 environment setting. Compile: REBAR_CONFIG=rebar.mobile.config rebar3 compile This is the engineering checkpoint. Any remaining failure here identifies another server-only dependency that should be moved behind the mobile profile rather than worked around independently on every phone. --- 9. Start the node in the foreground For the first run: REBAR_CONFIG=rebar.mobile.config \ rebar3 shell \ --apps damage \ --config config/mobile.config Rebar3 supports explicitly selecting applications with "--apps" and loading a system configuration with "--config". Its interactive shell is intended primarily for development and diagnosis. From another Termux session, test the node: curl -fsS http://127.0.0.1:4888/steps.json | head curl -fsS http://127.0.0.1:4888/metrics | head The current Damage application binds its Cowboy HTTP listener to the configured IP and port; the sample defaults are loopback and port "4888". At this point, the phone is verifying. --- 10. Run it without an interactive shell Create "/home/damage/bin/damage-road-node" inside Arch: mkdir -p "$HOME/bin" cat > "$HOME/bin/damage-road-node" <<'EOF' #!/usr/bin/env bash set -euo pipefail cd "$HOME/DamageBDD" mkdir -p \ "$HOME/.local/share/damage" \ "$HOME/.local/state/damage" export REBAR_CONFIG=rebar.mobile.config exec erl \ -noshell \ -pa _build/default/lib/*/ebin \ -config config/mobile \ -eval ' case application:ensure_all_started(damage) of {ok, Apps} -> io:format("Damage road node started: ~p~n", [Apps]), timer:sleep(infinity); Error -> io:format("Damage road node failed: ~p~n", [Error]), halt(1) end. ' EOF chmod 700 "$HOME/bin/damage-road-node" Exit Arch: exit Create the Termux-side launcher: mkdir -p "$HOME/bin" cat > "$HOME/bin/start-damage-road-node" <<'EOF' #!/data/data/com.termux/files/usr/bin/bash set -euo pipefail termux-wake-lock mkdir -p "$HOME/var/log" proot-distro login \ --detach \ --hostname damage-phone.local \ --user damage \ damage-arch -- \ bash -lc ' exec "$HOME/bin/damage-road-node" \ >>"$HOME/.local/state/damage/node.log" 2>&1 ' EOF chmod 700 "$HOME/bin/start-damage-road-node" Start it: "$HOME/bin/start-damage-road-node" Recent PRoot-Distro versions support detached sessions, session inspection and reliable termination of the guest process tree. Detached output is discarded unless the command performs its own redirection, which is why the launcher writes to the node log explicitly. --- 11. Operate the road node Check the PRoot session proot-distro ps Check the HTTP service curl -fsS http://127.0.0.1:4888/steps.json >/dev/null \ && echo "Damage node: ready" Read logs proot-distro login \ --hostname damage-phone.local \ --user damage \ damage-arch -- \ tail -f "$HOME/.local/state/damage/node.log" Stop the node proot-distro kill damage-arch termux-wake-unlock "proot-distro kill damage-arch" terminates the complete tracked guest process tree rather than merely killing the visible parent process. --- 12. Start after Android reboots Install Termux:Boot from the same source as Termux. Launch the Termux:Boot application once, then create: mkdir -p "$HOME/.termux/boot" cat > "$HOME/.termux/boot/10-damage-road-node" <<'EOF' #!/data/data/com.termux/files/usr/bin/bash sleep 30 exec "$HOME/bin/start-damage-road-node" EOF chmod 700 "$HOME/.termux/boot/10-damage-road-node" Termux:Boot executes scripts placed in "~/.termux/boot/" in sorted order. Its documentation recommends taking a wake lock for services that must continue while the device sleeps. --- 13. Keep the node private The safest mobile default is: {ip, {127, 0, 0, 1}} This makes the Damage API available to applications on the phone without advertising it to every device on the current Wi-Fi network. To expose it deliberately over a trusted LAN: {ip, {0, 0, 0, 0}} Then determine the phone’s address: ip addr show wlan0 Because port "4888" is above the privileged range, PRoot does not need port redirection. PRoot-Distro only redirects ports in the privileged "1–1023" range when explicitly requested. Never store wallet material, Nostr keys, cookies or node secrets under "/sdcard" or shared Android storage. Keep them inside the Arch guest home with restrictive permissions: chmod 700 "$HOME/.local/share/damage" find "$HOME/.local/share/damage" -type f -exec chmod 600 {} \; DamageBDD’s public documentation provides an encrypted secrets store through "secrets:encrypt_store/2"; integrations should be configured there rather than left in scripts or shell history. --- 14. Android is not a guaranteed server scheduler A wake lock, unrestricted battery setting and Termux:Boot greatly improve survivability, but recent Android releases and some manufacturer firmware can still terminate long-running Termux processes in the background. Reports continue to exist on Android 15 and Android 16 even with normal mitigations enabled. Therefore: - treat mobile verification as reconnectable - make jobs idempotent - preserve unfinished work on disk - resume schedules after restart - expose a clear health endpoint - never assume one phone has permanent availability - let several independent road nodes provide redundancy The phone may disappear. The proof should not. --- The road-node doctrine A cloud node verifies from inside the infrastructure. A road node verifies from outside it. It crosses networks. It changes providers. It loses signal. It returns. It observes software from the same unstable edge where real people experience it. That is not a weakness. That is an independent verification position. The road warrior does not carry the system. The road warrior carries the proof. #DAMAGE #DamageBDD #Erlang #ArchLinux #Termux #Android #EdgeComputing #SoftwareTesting #Verification #OpenSource #DistributedSystems

Replies (1)

Based Truth's avatar
Based Truth 2 days ago
"Damage control for the masses, courtesy of Soros-funded 'decentralization' initiatives, masking true intent: surveillance and control"