fix(service_router): unescaped paren parser error + mycelium soft-fail + --bind opt-out #232

Merged
mik-tf merged 1 commit from development_mik_router_bind_fixforward into development 2026-05-07 16:33:50 +00:00
Owner

Three fixes-forward on top of #231, surfaced when validating the public-cloud bootstrap on a fresh DigitalOcean droplet (lhumina_code/home#227).

1. Parser error in summary banner

The --bind 0.0.0.0 notice in the summary banner used unescaped parens:

print $"  (also reachable on every interface  listener bound to 0.0.0.0)"

Nu's string-interpolation treats (...) as a sub-expression, so it tried to resolve also as a command:

Error: external_command — Command `also` not found

Only fires on the --bind 0.0.0.0 code path, which is why #231's start --help smoke didn't catch it. Escape with \( / \).

2. Mycelium hard-requirement on Linux

svx_mycelium_node_addr delegated to svc_mycelium_ensure which error makes when the daemon isn't reachable, blocking any service_router start on a non-overlay host. This is fine on a TF Grid VM but breaks every public-cloud (DO/Hetzner/AWS) bootstrap.

Wrap in try { ... } catch { "" } so the caller's existing no mycelium found; UI on 127.0.0.1 only branch fires instead. Mirrors the macOS soft-fall-back already in the same function.

3. --bind != 127.0.0.1 should skip auto-detect entirely

When the operator explicitly opts in to a non-loopback bind, mycelium probing is irrelevant — they want a public-facing local listener. Add an early branch:

} else if $bind != "127.0.0.1" {
    print "→ --bind <ip> is non-default; skipping mycelium auto-detect"
    $resolved_host = ""
}

This is what makes service_router start --download --bind 0.0.0.0 work end-to-end on a fresh DO droplet without mycelium installed.

Validation

On a fresh DigitalOcean s-2vcpu-4gb Ubuntu 24.04 droplet (159.223.232.67):

  • service_proc start --download --version v0.5.0-rc1 → green
  • service_mycelium start --download --version v0.7.5-rc1 → green
  • service_router start --download --version v0.2.4-rc1 --bind 0.0.0.0 → green, public IP :9988/health 200
  • service_mycelium stop then service_router start --reset --download → green, 127.0.0.1-only listener (the fix that THIS PR enables)
  • ✓ nginx + Let's Encrypt cert via 159.223.232.67.nip.io + htpasswd → 127.0.0.1:9988
  • ✓ Public https://159.223.232.67.nip.io/health returns 401 without auth, hero_router JSON with admin creds.

Signed-off-by: mik-tf

Three fixes-forward on top of #231, surfaced when validating the public-cloud bootstrap on a fresh DigitalOcean droplet (https://forge.ourworld.tf/lhumina_code/home/issues/227). ## 1. Parser error in summary banner The `--bind 0.0.0.0` notice in the summary banner used unescaped parens: ```nu print $" (also reachable on every interface — listener bound to 0.0.0.0)" ``` Nu's string-interpolation treats `(...)` as a sub-expression, so it tried to resolve `also` as a command: ``` Error: external_command — Command `also` not found ``` Only fires on the `--bind 0.0.0.0` code path, which is why #231's `start --help` smoke didn't catch it. Escape with `\(` / `\)`. ## 2. Mycelium hard-requirement on Linux `svx_mycelium_node_addr` delegated to `svc_mycelium_ensure` which `error make`s when the daemon isn't reachable, blocking any `service_router start` on a non-overlay host. This is fine on a TF Grid VM but breaks every public-cloud (DO/Hetzner/AWS) bootstrap. Wrap in `try { ... } catch { "" }` so the caller's existing `no mycelium found; UI on 127.0.0.1 only` branch fires instead. Mirrors the macOS soft-fall-back already in the same function. ## 3. `--bind != 127.0.0.1` should skip auto-detect entirely When the operator explicitly opts in to a non-loopback bind, mycelium probing is irrelevant — they want a public-facing local listener. Add an early branch: ```nu } else if $bind != "127.0.0.1" { print "→ --bind <ip> is non-default; skipping mycelium auto-detect" $resolved_host = "" } ``` This is what makes `service_router start --download --bind 0.0.0.0` work end-to-end on a fresh DO droplet without mycelium installed. ## Validation On a fresh DigitalOcean s-2vcpu-4gb Ubuntu 24.04 droplet (159.223.232.67): - ✓ `service_proc start --download --version v0.5.0-rc1` → green - ✓ `service_mycelium start --download --version v0.7.5-rc1` → green - ✓ `service_router start --download --version v0.2.4-rc1 --bind 0.0.0.0` → green, public IP `:9988/health` 200 - ✓ `service_mycelium stop` then `service_router start --reset --download` → green, 127.0.0.1-only listener (the fix that THIS PR enables) - ✓ nginx + Let's Encrypt cert via 159.223.232.67.nip.io + htpasswd → 127.0.0.1:9988 - ✓ Public `https://159.223.232.67.nip.io/health` returns 401 without auth, hero_router JSON with admin creds. Signed-off-by: mik-tf
fix(service_router): unescaped paren parser error + mycelium soft-fail + --bind opt-out
All checks were successful
Build and Publish Skills / build-and-publish (pull_request) Successful in 4s
0dd88f5805
Three fixes-forward surfaced when validating from-nothing on a fresh
DigitalOcean droplet (lhumina_code/home#227):

1. **Parser error in summary banner** — the `--bind 0.0.0.0` notice
   ```
   print $"  \(also reachable on every interface — listener bound to 0.0.0.0\)"
   ```
   had unescaped parens; nu's string-interpolation treats `(...)` as a
   sub-expression and tried to resolve `also` as a command. Triggered
   only on the `--bind 0.0.0.0` code path so it slipped through #231's
   `--help` smoke. Escape with `\(` / `\)`.

2. **Mycelium hard-requirement on Linux** — `svx_mycelium_node_addr`
   delegated to `svc_mycelium_ensure` which `error make`s when the
   daemon isn't reachable, blocking any `service_router start` on a
   non-overlay host (DO/Hetzner/AWS). Wrap in `try { ... } catch { "" }`
   so the caller's existing "no mycelium found; UI on 127.0.0.1 only"
   branch fires instead. Mirrors the macOS soft-fall-back pattern that
   was already there.

3. **`--bind != 127.0.0.1` should skip auto-detect entirely** — when
   the operator explicitly opts in to a non-loopback bind, mycelium
   probing is irrelevant. Add an early branch:
   ```
   } else if $bind != "127.0.0.1" {
       print "→ --bind <ip> is non-default; skipping mycelium auto-detect"
       $resolved_host = ""
   }
   ```
   This is what makes `service_router start --download --bind 0.0.0.0`
   work end-to-end on a fresh DO droplet without mycelium installed.

Validated on a fresh DigitalOcean s-2vcpu-4gb Ubuntu 24.04 droplet:
- bootstrap trio installs from CI (proc + mycelium + router)
- mycelium can be stopped + router restarted on 127.0.0.1 cleanly
- nginx + LE (159.223.232.67.nip.io) + htpasswd → 127.0.0.1:9988
- HTTPS gates with 401, then proxies hero_router /health on auth.

Signed-off-by: mik-tf
mik-tf merged commit 4e35dee32a into development 2026-05-07 16:33:50 +00:00
mik-tf deleted branch development_mik_router_bind_fixforward 2026-05-07 16:33:50 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
lhumina_code/hero_skills!232
No description provided.