From a78e22933ee5eef5d6c12358bb1a4ad2e6b75b38 Mon Sep 17 00:00:00 2001 From: pstayet Date: Thu, 23 Jul 2026 15:05:28 -0700 Subject: [PATCH] fix(pilotctl): default beacon to the production address, honor PILOT_BEACON MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Symptom: the documented bootstrap flow pilotctl init --hostname my-agent pilotctl daemon start writes a dead beacon (127.0.0.1:9001) into ~/.pilot/config.json while writing the production registry (34.71.57.205:9000) into the same file. A node bootstrapped this way registers fine but cannot traverse NAT — its beacon points at localhost where nothing is listening. Three code locations conspired: 1. cmdInit: beaconAddr := flagString(flags, "beacon", "127.0.0.1:9001") — localhost fallback, inconsistent with the registry default in the same function ("34.71.57.205:9000"). 2. buildDaemonArgs: when config lacked a beacon it injected "127.0.0.1:9001", and it never consulted PILOT_BEACON — while the registry path in the same function resolves flag > config > env > hardcoded default (via getRegistry). 3. cmd/daemon's own default IS the production beacon ("34.71.57.205:9001", with $PILOT_BEACON support), but pilotctl always passes an explicit --beacon, so the daemon's correct default was unreachable through the documented start path. pilotctl's own `daemon start --help` already documents "--beacon beacon address (default: $PILOT_BEACON or 34.71.57.205:9001)" — this change makes the code match its shipped help. Fix: both pilotctl fallbacks now use 34.71.57.205:9001, and beacon resolution gains a getBeacon() helper mirroring getRegistry() exactly, closing the env-precedence gap (flag > config > PILOT_BEACON > default). Blast radius: - Every 127.0.0.1:9001 in tests is a local test *registry* listen address (registry.New / NewWithStore) or an explicit SetBeaconAddr — none depends on the removed pilotctl fallback. - Installer users are unaffected: both install.sh in this repo and the one in pilot-protocol/release write an explicit "beacon" key into config.json and pass -beacon in the service units. - Local-dev beacons still work via --beacon, the config key, or (new) PILOT_BEACON — the same three escape hatches the registry has. Verified: gofmt clean; go build ./cmd/... ok; go test ./cmd/pilotctl ok. Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_0142ryqVGEmJN66VZtCC7wFD --- cmd/pilotctl/main.go | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/cmd/pilotctl/main.go b/cmd/pilotctl/main.go index be88c34b..7d32c9bf 100644 --- a/cmd/pilotctl/main.go +++ b/cmd/pilotctl/main.go @@ -288,6 +288,23 @@ func getRegistry() string { return "34.71.57.205:9000" } +// getBeacon mirrors getRegistry for the beacon address: env override, +// then config, then the production beacon — the same default compiled +// into pilot-daemon itself (cmd/daemon). Keeping the two in lockstep +// matters because pilotctl always passes an explicit --beacon to the +// daemon, so a divergent fallback here would silently override the +// daemon's own correct default. +func getBeacon() string { + if v := os.Getenv("PILOT_BEACON"); v != "" { + return v + } + cfg := loadConfig() + if s, ok := cfg["beacon"].(string); ok && s != "" { + return s + } + return "34.71.57.205:9001" +} + func loadConfig() map[string]interface{} { f, err := os.Open(configPath()) if err != nil { @@ -2011,7 +2028,7 @@ func cmdInit(args []string) { flags, _ := parseFlags(args) registryAddr := flagString(flags, "registry", "34.71.57.205:9000") - beaconAddr := flagString(flags, "beacon", "127.0.0.1:9001") + beaconAddr := flagString(flags, "beacon", "34.71.57.205:9001") hostname := flagString(flags, "hostname", "") socketPath := flagString(flags, "socket", defaultSocket()) @@ -2647,7 +2664,7 @@ func buildDaemonArgs(args []string) (daemonArgs []string, socketPath string, adm if b, ok := cfg["beacon"].(string); ok { beaconAddr = b } else { - beaconAddr = "127.0.0.1:9001" + beaconAddr = getBeacon() } } listenAddr := flagString(flags, "listen", ":0")