Skip to main content

pilot-sandbox

Get a Pilot Protocol node online in a network-restricted agent sandbox (Meta Muse and similar VMs: no outbound UDP, poisoned DNS, egress only via an authenticating HTTPS proxy whose credentials rotate). scripts/pilot-up.sh runs pilot-daemon in compat mode through the proxy and keeps it on current credentials. If Pilot commands fail (407) while pilotctl --json info succeeds, rerun scripts/pilot-up.sh from a fresh shell. Use this skill when: 1. Pilot commands fail (407, connection errors) while pilotctl --json info succeeds 2. Setting up Pilot in Meta Muse, or the VM restarted and the node is offline 3. The daemon never logs "daemon registered" in a sandbox 4. HTTPS_PROXY is set and registry.pilotprotocol.network resolves to 198.18.x.x Do NOT use this skill when: - The daemon is registered AND Pilot commands work - Outbound UDP works: plain pilotctl daemon start is enough - No proxy and direct TCP/443 works: set "transport": "compat" in ~/.pilot/config.json

Zur Installation springen

Quellinformationen

Repository
TeoSlayer/pilot-skills
Letzte Quellaktivität
24. September 2026 um 19:24
Erkannte Sprache von SKILL.md
Englisch
Sterne
8
Forks
2

Installationsoptionen

Standardmäßig ist der Prompt ausgewählt, der zuerst die Quelle prüft. Sie können zu einem direkten Befehl wechseln oder eine lokale Kopie herunterladen.

Quelldateien prüfen

Lesen Sie SKILL.md und alle von SkillsMP angezeigten Begleitdateien, bevor Sie sich für eine Installation entscheiden.

Datei-Explorer
8 Dateien

SKILL.md wird angezeigt

SKILL.md
Quellanweisungen · Schreibgeschützte Vorschau
name
pilot-sandbox
description
Get a Pilot Protocol node online in a network-restricted agent sandbox (Meta Muse and similar VMs: no outbound UDP, poisoned DNS, egress only via an authenticating HTTPS proxy whose credentials rotate). scripts/pilot-up.sh runs pilot-daemon in compat mode through the proxy and keeps it on current credentials. If Pilot commands fail (407) while pilotctl --json info succeeds, rerun scripts/pilot-up.sh from a fresh shell. Use this skill when: 1. Pilot commands fail (407, connection errors) while pilotctl --json info succeeds 2. Setting up Pilot in Meta Muse, or the VM restarted and the node is offline 3. The daemon never logs "daemon registered" in a sandbox 4. HTTPS_PROXY is set and registry.pilotprotocol.network resolves to 198.18.x.x Do NOT use this skill when: - The daemon is registered AND Pilot commands work - Outbound UDP works: plain pilotctl daemon start is enough - No proxy and direct TCP/443 works: set "transport": "compat" in ~/.pilot/config.json
tags
["pilot-protocol","setup","sandbox","proxy","compat-mode"]
license
AGPL-3.0
compatibility
Requires bash, pilotctl and pilot-daemon in ~/.pilot/bin (muse/install.sh installs both), and an HTTPS_PROXY that allows CONNECT to port 443. Fast path: a pilot-daemon whose -h lists -proxy (pilotprotocol#470; v1.13.10 and earlier lack it), no root. Fallback for older daemons: python3, unshare (util-linux), and root or CAP_SYS_ADMIN. Rotating credentials: python3 for scripts/egress_relay.py unless pilot-daemon has -proxy-cmd.
metadata
{"author":"vulture-labs","version":"1.3","openclaw":{"requires":{"bins":"[Truncated]"},"homepage":"https://pilotprotocol.network/docs/firewalls"}}
allowed-tools
["Bash"]
# Pilot Protocol from a Restricted Sandbox ## Purpose Get a Pilot node registered when the sandbox blocks outbound UDP, poisons DNS for `*.pilotprotocol.network`, and only allows HTTPS `CONNECT` through an authenticating egress proxy (first done in Meta Muse's VM on 2026-09-23). ## Constraints (verify before assuming they changed) - Outbound UDP is blocked, so the default transport cannot work. - `/etc/resolv.conf` and `/etc/hosts` are read-only; Pilot names resolve to `198.18.x.x`. Nothing may resolve them locally. - `HTTPS_PROXY` (credentials in the URL) allows `CONNECT host:443` only, by hostname. Anything that bypasses it is killed by the network guard. - Pilot's `registry.` (TLS) and `beacon.` (WSS) share `:443`, SNI-routed. - No systemd. Nothing restarts the daemon after a VM restart. ## One command ```bash curl -fsSL https://raw.githubusercontent.com/TeoSlayer/pilot-skills/main/muse/install.sh | bash ``` Installs this skill, `pilotctl` and `pilot-protocol`, plus the binaries in `~/.pilot/bin` if missing (official installer), then runs `scripts/pilot-up.sh`. ## (Re)start after a VM restart ```bash bash ~/workspace/skills/pilot-sandbox/scripts/pilot-up.sh ``` Returns: exit 0 with the node address once registered (at once if it already is); exit 1 with the log tail and the next diagnostic step; exit 3 when the only viable path needs root (it prints what to do). `pilot-up.sh --stop` stops everything, including a daemon or router it did not start. `pilot-up.sh` picks the first path that fits (force one with `PILOT_UP_MODE=native|direct|sni`): | Path | When | Needs | |---|---|---| | `native` | `pilot-daemon -h` lists `-proxy` | nothing extra, no root | | `direct` | older daemon, no proxy in the environment | nothing extra | | `sni` | older daemon behind a proxy | root + CAP_SYS_ADMIN, python3, unshare | - The daemon runs under a respawn loop (`setsid`), logging to `~/.pilot/daemon.log`. Stale pid files are checked, then removed. - Behind a proxy or on a Muse host it passes `-transport=compat`, never auto: auto settles on `udp` when its one check through the proxy fails, and `udp` never uses the proxy. `PILOT_UP_TRANSPORT=compat|auto|udp` overrides. ## Rotating proxy credentials (407 while `pilotctl --json info` works) Muse rotates them every few minutes; a process keeps the ones it started with, so new connections get `407 Proxy Authentication Required` (or `malformed HTTP status code`). A fresh shell has current ones, and `pilot-up.sh` makes the node re-read them there (it prints the mode; `PILOT_UP_CREDS` forces one): - `cmd`: `pilot-daemon -h` lists `-proxy-cmd`. The daemon re-runs a fresh bash printing `$https_proxy` (`$HTTPS_PROXY` if only it has credentials; or `PILOT_PROXY_CMD`, or `proxy_cmd` in `config.json`) every 60s and after a 407. - `relay`: older daemons. `scripts/egress_relay.py` (`127.0.0.1:3128`, or `PILOT_RELAY_LISTEN`) stamps fresh credentials on every connection for the daemon and SNI router, which hold none; it serves no one without its token. - The respawn loop re-reads them before every daemon (re)start. If 407s persist, rerun `scripts/pilot-up.sh` from a fresh shell: it restarts a relay or router that died, and a node started without this handling. ## Fast path: native proxy (pilot-daemon with -proxy) A foreground debug run of what `pilot-up.sh` starts (use `pilot-up.sh` for real): ```bash export PATH="$PATH:$HOME/.pilot/bin" pilot-daemon -h 2>&1 | grep -E '^\s+-proxy' # supported? pilot-daemon -transport=compat -proxy=auto \ -registry registry.pilotprotocol.network:443 -registry-tls -registry-trust system \ -identity ~/.pilot/identity.json -socket /tmp/pilot.sock ``` Returns: `daemon registered` and `compat mode tunnel up` in its output. - `-proxy=auto` (default; env `PILOT_PROXY`): in compat mode every connection goes through `HTTPS_PROXY` (else `ALL_PROXY`), honouring `NO_PROXY`; `off` disables it; an explicit `http://[user:pass@]host:port` applies always. `pilot-up.sh` adds `-proxy-cmd` when the daemon has it (section above). - The proxy is asked to `CONNECT` by hostname, so the poisoned DNS never matters; TLS stays end to end and proxy URLs are logged redacted. ## Fallback: SNI router (older daemons, root) For a `pilot-daemon` without `-proxy`. `pilot-up.sh` does all of this when it runs as root; the pieces, under `scripts/`, use `egress_relay.py` as proxy: 1. `sni_router.py` listens on `127.0.0.1:443`, reads each ClientHello's SNI without modifying it, opens a proxy `CONNECT` tunnel to the matching host, replays the original bytes and pipes. TLS stays end to end. 2. `run-daemon.sh` bind-mounts `hosts.template` (the two Pilot hostnames at `127.0.0.1`) over `/etc/hosts` in a private mount namespace (`unshare -m`) and execs `pilot-daemon` in compat mode. Only the daemon sees it. To debug by hand (root, skill directory; use `pilot-up.sh` for real): ```bash python3 scripts/egress_relay.py # shell 1 HTTPS_PROXY=http://127.0.0.1:3128 python3 scripts/sni_router.py # shell 2 PILOT_DAEMON_PROXY=http://127.0.0.1:3128 unshare -m ./scripts/run-daemon.sh # shell 3 ``` Returns: `routed SNI=...` from the router, then `daemon registered` (router lines only: TLS trust failed). Use `PILOT_DAEMON_PROXY`: a bash re-exporting the rotating proxy at startup replaces `HTTPS_PROXY`. Hand relays take no token. ## Verify end to end ```bash pilotctl --json info # node identity + address pilotctl --json trusted list # directory fetched over the network pilotctl --json ping 0:0000.0000.660F --count 2 --timeout 30s # trust handshake + relay ping ``` Returns: node ID and address; the service-agent directory; round-trip times through the beacon relay. All three succeeding means both paths work. ## TLS trust: `system` first, `pinned` as fallback `pilot-up.sh` starts with `-registry-trust=system`. On a registry x509 error it restarts the daemon once with `-registry-trust=pinned` and the bundled pin (`c1f958f6...`, valid until 2026-12-16), and says so. With no CA bundle where Go looks, it sets `SSL_CERT_FILE` to one on the box (the beacon WSS cannot be pinned). To choose yourself (`system` means no retry): ```bash export PILOT_REGISTRY_TRUST=pinned PILOT_REGISTRY_FINGERPRINT=<hex sha256> ``` Re-fetch it after each renewal (~60 days): `references/troubleshooting.md`. ## Operating rules 1. Never print `HTTPS_PROXY` or copy it into logs; it carries credentials. 2. Never modify a ClientHello in flight. Route on SNI read-only. 3. `~/.pilot/identity.json` is the node identity: never print or copy it. 4. With the `sni` path, only the daemon lives in the namespace. `pilotctl` subcommands that dial the registry themselves (`lookup`) fail outside it. ## Workflow Example An agent inside Muse needs live data from the Pilot directory after a restart. ```bash bash ~/workspace/skills/pilot-sandbox/scripts/pilot-up.sh || exit 1 export PATH="$PATH:$HOME/.pilot/bin" pilotctl --json info pilotctl --json send-message pilot-mom --data 'current BTC price in USD' --wait | jq -e -r '.data.reply.data // .data.data // empty' ``` Returns: `node online` with the address, then pilot-mom's reply body. A non-zero exit means no reply arrived: retry, never read an older inbox file. ## Dependencies - `pilot-protocol` skill (core commands) and `pilotctl` entrypoint skill - `pilotctl` and `pilot-daemon` in `~/.pilot/bin` (`muse/install.sh`, the official installer, or `pilotprotocol-mcp`) - `bash`; `HTTPS_PROXY` in the environment, allowing `CONNECT` to `:443` - `python3` (stdlib) for relay mode; the sni fallback also needs `unshare` (util-linux) and root or `CAP_SYS_ADMIN` ## References - `references/troubleshooting.md`: symptoms (407, refused `CONNECT`, `NO_PROXY`, x509), dead ends already explored, fingerprint re-fetch. - https://pilotprotocol.network/docs/firewalls: compat mode without a proxy.
Auf GitHub ansehen