From a643f9d0008cea4b085b484fbdb7f05081960eef Mon Sep 17 00:00:00 2001
From: emilbob
Date: Sun, 26 Jul 2026 00:07:23 +0200
Subject: [PATCH] Link the two deployments to each other
The Render service runs the real binary; the Pages copy runs the
JavaScript engine. Someone landing on the second should be told where
the first is rather than left with the caveat and no way to act on it.
Also records the trade rather than just the URLs: Render's free tier
sleeps after ~15 minutes idle so the first request wakes it, while the
static copy has no backend to wait on and is always instant.
Co-Authored-By: Claude Opus 5
---
README.md | 13 ++++++++-----
web/index.html | 6 ++++--
2 files changed, 12 insertions(+), 7 deletions(-)
diff --git a/README.md b/README.md
index 59b0850..f6e724f 100644
--- a/README.md
+++ b/README.md
@@ -104,16 +104,19 @@ The `HandshakeMessage` struct in `src/scale.rs` is a worked example of SCALE enc
## Try it in a browser
-**→ [emilbob.github.io/substrate-node-probe](https://emilbob.github.io/substrate-node-probe/)**
+**→ [substrate-node-probe.onrender.com](https://substrate-node-probe.onrender.com/)** — runs the real binary
+**→ [emilbob.github.io/substrate-node-probe](https://emilbob.github.io/substrate-node-probe/)** — runs in your tab
The same checks against a live node, with results filling in as they resolve. Source is [`web/index.html`](web/index.html) — one self-contained file, no build step.
The page runs the checks one of two ways, and always says which:
-| Engine | When | What actually runs |
+| Engine | Where | What actually runs |
| --- | --- | --- |
-| **JavaScript** | Static hosting, e.g. GitHub Pages | A reimplementation of the checks in the browser tab, connecting straight to the node. Nothing is proxied. |
-| **Rust** | Served by `serve` (see below) | The real binary, server-side. The report is its output, unmodified. |
+| **Rust** | Render | The real binary, server-side. The report is its output, unmodified. |
+| **JavaScript** | GitHub Pages, or any static host | A reimplementation of the checks in the browser tab, connecting straight to the node. Nothing is proxied. |
+
+Render's free tier sleeps after ~15 minutes idle, so the first request after a quiet spell takes a while to wake. The Pages copy has no backend to wait on and is always instant — which is the honest trade between the two.
The page asks `/api/health` on load; if a backend answers, it offers the switch and defaults to Rust. On a static host there is nothing to switch to, so it stays in browser mode and says so rather than implying the binary ran.
@@ -140,7 +143,7 @@ curl -s localhost:8080/api/probe -H 'Content-Type: application/json' \
It is feature-gated, so a plain `cargo build` still produces only the CLI without compiling a web stack it will never call.
-[`render.yaml`](render.yaml) provisions it on [Render](https://render.com) from the [`Dockerfile`](Dockerfile) — *New → Blueprint → pick this repo*. On Render's free tier the service sleeps after ~15 minutes idle, so the first request after a quiet spell is slow.
+[`render.yaml`](render.yaml) provisions it on [Render](https://render.com) from the [`Dockerfile`](Dockerfile) — *New → Blueprint → pick this repo*, nothing to configure by hand. That is what runs at [substrate-node-probe.onrender.com](https://substrate-node-probe.onrender.com/).
### Running it for strangers is not running it for yourself
diff --git a/web/index.html b/web/index.html
index 070086c..5e3fb84 100644
--- a/web/index.html
+++ b/web/index.html
@@ -231,7 +231,8 @@ substrate-node-probe
JavaScript reimplementation of the same checks, speaking the same JSON-RPC over the same
WebSocket — same request ids, same failure kinds, same rule that an unprovable requirement
fails rather than passes. The connection is made directly from your browser to the node you
- name; nothing is proxied and no data leaves your machine.
+ name; nothing is proxied and no data leaves your machine. To run the actual binary instead,
+ use the deployment that hosts it.