
Protocolo de red superpuesta que brinda a los agentes de IA direcciones permanentes, túneles cifrados autenticados y un modelo de confianza sobre UDP. Incluye traversía NAT, mensajería peer-to-peer y SDK para Node.js, Python y Swift.
<p align="center">
<img src="https://assets.kitploit.com/production/public/readmes/13790/aca1679f7d00fe2469f0e9f72a440a9bcbe7d0448446e1d15a79f0669bdc3d18.png" alt="Pilot Protocol" width="200">
</p>
<h1 align="center">Pilot Protocol</h1>
<p align="center">
<strong>La pila de red para agentes de IA.</strong><br>
Direcciones. Puertos. Túneles. Cifrado. Confianza.
</p>
<p align="center">
<a href="https://pilotprotocol.network/docs/"><strong>Docs</strong></a>
<span> · </span>
<a href="https://github.com/pilot-protocol/docs/blob/main/SPEC.md"><strong>Wire Spec</strong></a>
<span> · </span>
<a href="https://github.com/pilot-protocol/docs/blob/main/WHITEPAPER.pdf"><strong>Whitepaper</strong></a>
<span> · </span>
<a href="https://www.ietf.org/archive/id/draft-teodor-pilot-protocol-01.html"><strong>IETF Draft</strong></a>
<span> · </span>
<a href="https://github.com/TeoSlayer/pilot-skills"><strong>Agent Skills</strong></a>
<span> · </span>
<a href="https://polo.pilotprotocol.network"><strong>Polo (Live Dashboard)</strong></a>
</p>
<br>
<p align="center">
<img src="https://img.shields.io/badge/lang-Go-00ADD8?logo=go&logoColor=white" alt="Go">
<img src="https://img.shields.io/badge/core-stdlib-brightgreen" alt="Core uses Go standard library only">
<img src="https://img.shields.io/badge/encryption-AES--256--GCM-blueviolet" alt="Encryption">
<img src="https://img.shields.io/badge/tests-1048%20pass-success" alt="Tests">
<a href="https://www.ietf.org/archive/id/draft-teodor-pilot-protocol-01.html"><img src="https://img.shields.io/badge/IETF-Internet--Draft-blue" alt="IETF Internet-Draft"></a>
<img src="https://img.shields.io/badge/license-AGPL--3.0-blue" alt="License">
</p>
---
<p align="center">
<img src="https://assets.kitploit.com/production/public/readmes/13790/290649ca3b8051e074e6f0b5f3bda2c43eeeb40e86686f8767bf9734269912cc.gif" alt="Pilot Protocol Demo — two agents: install, trust, data exchange" width="960">
</p>
Internet fue construido para humanos. Los agentes de IA no tienen dirección, ni identidad, ni forma de ser alcanzados. Pilot Protocol es una red superpuesta que les da a los agentes lo que internet les dio a los dispositivos: **una dirección permanente, canales cifrados autenticados y un modelo de confianza** -- todo ello sobre UDP estándar.
Los agentes se registran en un servicio de rendezvous para el descubrimiento y la traversía de NAT. Los datos de la aplicación fluyen directamente entre pares por la ruta directa; cuando el hole-punching de NAT falla (por ejemplo, NAT simétrico), el beacon retransmite el tráfico, que sigue estando cifrado de extremo a extremo, como respaldo. No es una API. No es un framework. Es infraestructura.
---
## El problema
Hoy, los agentes se comunican a través de APIs centralizadas. Cada mensaje pasa por una plataforma -- la plataforma ve todo el tráfico, controla el acceso y se convierte en un único punto de fallo.
```mermaid
graph LR
A1[Agent A] -->|HTTP API| P[Platform / Cloud]
A2[Agent B] -->|HTTP API| P
A3[Agent C] -->|HTTP API| P
style P fill:#f66,stroke:#333,color:#fff
style A1 fill:#4a9,stroke:#333,color:#fff
style A2 fill:#4a9,stroke:#333,color:#fff
style A3 fill:#4a9,stroke:#333,color:#fff
```
El Protocolo Pilot saca a la plataforma de la ruta de datos. Un servicio ligero de **rendezvous** gestiona el descubrimiento y la travesía de NAT, pero una vez que los agentes se encuentran entre sí, se comunican directamente a través de túneles autenticados y cifrados:
```mermaid
graph LR
A1[Agent A<br/><small>0:0000.0000.0001</small>] <-->|Encrypted UDP Tunnel| A2[Agent B<br/><small>0:0000.0000.0002</small>]
A1 <-->|Encrypted UDP Tunnel| A3[Agent C<br/><small>0:0000.0000.0003</small>]
A2 <-->|Encrypted UDP Tunnel| A3
A1 -.->|discovery| RV[Rendezvous]
A2 -.->|discovery| RV
A3 -.->|discovery| RV
style A1 fill:#4a9,stroke:#333,color:#fff
style A2 fill:#4a9,stroke:#333,color:#fff
style A3 fill:#4a9,stroke:#333,color:#fff
style RV fill:#888,stroke:#333,color:#fff
```
## Qué obtienen los agentes
```bash
pilotctl info # show your address, hostname, peer count
pilotctl set-hostname my-agent # claim a name other agents can resolve
pilotctl find agent-alpha # resolve a public demo peer
pilotctl ping agent-alpha # round-trip over the encrypted tunnel
pilotctl bench agent-alpha # 1 MB echo benchmark
```
Una vez que tenga un par de confianza, la mensajería de agente a agente utiliza el servicio de intercambio de datos en el puerto 1001:
```bash
# Send a structured message (waits for reply by default)
pilotctl send-message other-agent --data "hello"
# Read messages delivered to your inbox
pilotctl inbox
# Read a specific message
pilotctl inbox read <id>
```
Para mensajería de puerto sin procesar de nivel inferior:
```bash
# on the sender
pilotctl send other-agent 1000 --data "hello"
# on the receiver
pilotctl recv 1000 --count 5 --timeout 30s
```
Cada comando de la CLI admite `--json` para obtener una salida estructurada — consulta la [referencia de la CLI](https://pilotprotocol.network/docs/cli-reference) para conocer toda la superficie disponible.
<details>
<summary><strong>Ejemplo de salida JSON</strong></summary>
```json
$ pilotctl --json info
{"status":"ok","data":{"address":"0:0000.0000.0005","node_id":5,"hostname":"my-agent","peers":3,"connections":1,"uptime_secs":3600}}
$ pilotctl --json find other-agent
{"status":"ok","data":{"hostname":"other-agent","address":"0:0000.0000.0003"}}
$ pilotctl --json recv 1000 --count 1
{"status":"ok","data":{"messages":[{"seq":0,"port":1000,"data":"hello","bytes":5}]}}
$ pilotctl --json find nonexistent
{"status":"error","code":"not_found","message":"cannot find \"nonexistent\" — hostname not found or no mutual trust","hint":"establish trust first: pilotctl handshake nonexistent \"reason\""}
```
</details>
---
## Acceso programático (SDKs)
Una vez que el daemon está en ejecución, puedes interactuar con los agentes de forma programática a través del SDK en lugar de la CLI. Los tres SDKs se comunican con el daemon local de Pilot mediante su IPC de socket Unix y exponen toda la superficie del agente — handshake, trust, send, receive, stream y gateway — en el lenguaje de tu elección.
| Lenguaje | Paquete | Inicio rápido |
|----------|---------|------------|
| **Node.js / TypeScript** | [`pilotprotocol` en npm](https://www.npmjs.com/package/pilotprotocol) | `npm install pilotprotocol` — consulta el [README de sdk-node](https://github.com/pilot-protocol/sdk-node) |
| **Python** | [`pilotprotocol` en PyPI](https://pypi.org/project/pilotprotocol/) | `pip install pilotprotocol` — consulta el [README de sdk-python](https://github.com/pilot-protocol/sdk-python) |
| **Swift / iOS / macOS** | [`pilotprotocol` en GitHub](https://github.com/pilot-protocol/sdk-swift) | Añádelo mediante `Package.swift` — consulta el [README de sdk-swift](https://github.com/pilot-protocol/sdk-swift) |
Un ejemplo mínimo de primera consulta en Node.js después de `daemon start`:
```js
import { createPilot, createAgent } from 'pilotprotocol';
const pilot = await createPilot();
const conn = await pilot.handshake('agent-alpha', 'hello');
await conn.trust();
// Send a message
await conn.send(3000, Buffer.from('ping'));
// Receive on any port
const msgs = await conn.recv(3000, { count: 1, timeout: 10 });
console.log('Received:', msgs[0].data.toString());
```
Consulta el README de cada SDK para obtener la documentación completa de la API, ejemplos de streaming y configuración específica de la plataforma (simulador de iOS, extras de PyPI, etc.).
## Aspectos destacados
<table>
<tr>
<td width="50%" valign="top">
**Direccionamiento**
- Direcciones virtuales de 48 bits (`N:NNNN.HHHH.LLLL`)
- Puertos de 16 bits con asignaciones conocidas
- Descubrimiento basado en nombres de host
**Transporte**
- Flujos confiables (equivalente a TCP)
- Ventana deslizante, SACK, control de congestión (AIMD)
- Control de flujo (ventana de recepción anunciada)
- Coalescencia de Nagle, segmentación automática, sondeo de ventana cero
- Travesía de NAT: descubrimiento STUN, hole-punching, respaldo por relay
</td>
<td width="50%" valign="top">
**Seguridad**
- Intercambio de claves autenticado (X25519 firmado con Ed25519 + AES-256-GCM)
- Claves de identidad Ed25519 vinculadas a sesiones de túnel
- Los nodos son privados por defecto
- Protocolo de handshake de confianza mutua (firmado, relay vía registro)
**Operaciones**
- Protocolo central: solo biblioteca estándar de Go
- Binario de daemon único con servicios integrados
- Registro JSON estructurado (`slog`)
- Persistencia atómica para todo el estado
- Replicación de registro en modo hot-standby
</td>
</tr>
</table>
---
## Arquitectura
```mermaid
graph LR
subgraph Local Machine
Agent[Your Agent] -->|commands| CLI[pilotctl]
CLI -->|Unix socket| D[Daemon]
D --- E[Echo :7]
D --- DX[Data Exchange :1001]
D --- ES[Event Stream :1002]
end
D <====>|UDP Tunnel<br/>AES-256-GCM + NAT traversal| RD
subgraph Remote Machine
RD[Remote Daemon] -->|Unix socket| RC[pilotctl]
RC -->|commands| RA[Remote Agent]
RD --- RE[Echo :7]
RD --- RDX[Data Exchange :1001]
RD --- RES[Event Stream :1002]
end
D -.->|register + discover| RV
RD -.->|register + discover| RV
subgraph Rendezvous
RV[Registry :9000<br/>Beacon :9001]
end
```
Tu agente se comunica con un **daemon** local a través de un socket Unix. El daemon gestiona el cifrado del túnel, la travesía de NAT, el enrutamiento de paquetes, el control de congestión y los servicios integrados. El daemon mantiene una conexión con un servidor de **rendezvous** (registro + beacon) para el registro de nodos, el descubrimiento de pares y el hole-punching de NAT. Una vez establecido un túnel, los datos fluyen directamente entre daemons -- el rendezvous no está en la ruta de datos, excepto cuando el beacon debe retransmitir tráfico para pares detrás de NATs simétricos (el tráfico retransmitido permanece cifrado de extremo a extremo).
Se proporciona un rendezvous público en `34.71.57.205:9000`, o puedes ejecutar el tuyo propio con `rendezvous -registry-addr :9000 -beacon-addr :9001`.
Para obtener detalles sobre el ciclo de vida de las conexiones, el puenteo de gateway y la estrategia de travesía de NAT, consulta la [documentación completa](https://pilotprotocol.network/docs/).
---
## Demo
Un agente de demostración público (`agent-alpha`) está ejecutándose en la red con la aceptación automática habilitada:
```bash
# 1. Install
curl -fsSL https://pilotprotocol.network/install.sh | sh
# 2. Start the daemon
pilotctl daemon start --hostname my-agent --email [email protected]
# 3. Request trust (auto-approved within seconds)
pilotctl handshake agent-alpha "hello"
# 4. Wait a few seconds, then verify trust
pilotctl trust
# 5. Start the gateway (maps the agent to a local IP)
sudo pilotctl extras gateway start --ports 80 0:0000.0000.0004
# 6. Open the website
curl http://10.4.0.1/
```
También puedes hacer ping y benchmark:
```bash
pilotctl ping agent-alpha
pilotctl bench agent-alpha
```
---
## Instalación
```bash
curl -fsSL https://pilotprotocol.network/install.sh | sh
```
Establecer un nombre de host y un correo electrónico durante la instalación:
```bash
curl -fsSL https://pilotprotocol.network/install.sh | [email protected] PILOT_HOSTNAME=my-agent sh
```
**UDP bloqueado, o la única salida es un proxy HTTPS** (sandboxes de agentes alojados como Meta Muse, VMs bloqueadas)? La instalación simple funciona:
```bash
curl -fsSL https://pilotprotocol.network/install.sh | sh
pilotctl daemon start
```
Las instalaciones nuevas usan el transporte `auto`: el daemon sondea el beacon por UDP una vez al arrancar (un round trip cuando UDP funciona, como máximo ~1.5s cuando no) y, cuando no hay respuesta pero el beacon de compatibilidad responde por TCP 443 (una petición TLS que un beacon activo responde con `426 Upgrade Required`), se ejecuta en modo **compat** — registro sobre TLS en `registry.pilotprotocol.network:443`, beacon sobre WSS en `beacon.pilotprotocol.network:443`. Cuando hay un proxy configurado y este rechaza esa comprobación (credenciales incorrectas o caducadas: `407`, un `403`, o el proxy no es accesible), se ejecuta en compat de todos modos en lugar de recurrir a conexiones directas saltándose el proxy, y el dial al registro entonces nombra la respuesta del proxy; `pilotctl daemon start` imprime el último error de proxy del daemon con una pista en lugar de solo "did not become ready". Cuando ninguno responde y no hay proxy involucrado (aún sin red, caída del beacon) se mantiene en UDP, como antes. En modo compat el daemon tuneliza a través de `$HTTPS_PROXY` / `$ALL_PROXY` (respetando `$NO_PROXY`), pidiendo al proxy que haga `CONNECT` por nombre de host, de modo que un DNS local envenenado para los hosts de Pilot no importa. Los propios comandos de registro de `pilotctl` (`lookup`, la comprobación de auto-handshake, `recovery`) siguen al daemon: a través del proxy cuando este se ejecuta en compat (o con una URL de proxy explícita), directamente cuando se ejecuta en UDP; sin ningún daemon en ejecución y sin transporte configurado, prueban primero el proxy y después una conexión directa. Para omitir el sondeo UDP, elige compat explícitamente: `sh -s -- --transport compat`, `pilotctl config --set transport=compat`, o `pilotctl daemon start --transport compat`.
- **No se necesita root, systemd ni launchd.** Inicia el daemon con `pilotctl daemon start` desde un shell que tenga las variables de proxy. En un contenedor o VM sin systemd el instalador también se ejecuta como root (el usuario del agente en sandboxes alojados); en un host normal sigue rechazando root a menos que `PILOT_ALLOW_ROOT=1`.
- **En un contenedor, dale al daemon un proceso init.** Las apps inician servidores que se daemonizan (redis, postgres); un servidor daemonizado se entrega al PID 1, y cuando se detiene permanece como zombi (`Z` en `ps`) hasta que el PID 1 lo recoja. Un `pilot-daemon` que es él mismo el PID 1 no lo hace, así que los zombis se acumulan y cuentan contra el límite de PID del contenedor. Ejecuta el contenedor con `docker run --init` (Compose: `init: true`), haz de [tini](https://github.com/krallin/tini) el entrypoint (`ENTRYPOINT ["tini", "--", "pilot-daemon"]`), o en Kubernetes establece `shareProcessNamespace: true` (ECS: `initProcessEnabled`). El daemon registra una advertencia al arrancar cuando es el PID 1; la ausencia de advertencia no prueba que todo esté bien si algún otro proceso sin recolección, como un script de shell, es el PID 1. No recolecta huérfanos por sí mismo: hacerlo en proceso también se llevaría el estado de salida de las apps que supervisa.
- **Proxy con credenciales:** mantenlas fuera de `ps` — exporta `HTTPS_PROXY` / `PILOT_PROXY`, o `pilotctl daemon start --proxy http://user:pass@host:port` (pilotctl entrega una URL con credenciales al daemon en su entorno, nunca en su línea de comandos). Para un servicio systemd/launchd, que no ve las variables de tu shell, guárdala: `pilotctl config --set proxy=http://user:pass@host:port` (config.json tiene permisos 0600).
- **Credenciales de proxy que rotan** (Meta Muse rota las credenciales en `HTTPS_PROXY` cada pocos minutos): un daemon de larga duración conservaría las que tenía al arrancar, y las conexiones nuevas empezarían a fallar con `407 Proxy Authentication Required` mientras los túneles antiguos siguen activos ("node online, apps broken"). Dale al daemon un comando que imprima la URL de proxy actual — `proxy_cmd` en config.json, `$PILOT_PROXY_CMD`, `-proxy-cmd` o `pilotctl daemon start --proxy-cmd` — y lo vuelve a ejecutar una vez transcurridos 60s y siempre que el proxy rechace las credenciales (un 407, o la respuesta corrupta de Muse "malformed HTTP status code"), reintentando esa conexión una vez con las credenciales nuevas (tanto el registro, como el beacon compat y los clientes HTTP, mediante el refresco de `netproxy` de common); no hace falta reiniciar. Las apps que el daemon inicia llegan al proxy a través de un relay de loopback en el daemon que añade las credenciales actuales, así que siguen funcionando a través de las rotaciones también. Los propios comandos de registro de pilotctl usan el mismo comando. En un contenedor/VM Linux sin systemd cuyo `HTTPS_PROXY` o `https_proxy` lleva credenciales, `pilotctl daemon start` entrega al daemon un `PILOT_PROXY_CMD` que imprime el `$https_proxy` de un bash nuevo (o `$HTTPS_PROXY` cuando solo ese lleva credenciales) siempre que no haya un `proxy_cmd` configurado, y el instalador guarda el mismo comando en config.json; en otros casos: `pilotctl config --set proxy_cmd="bash -c 'printf %s \"\$https_proxy\"'"`. Sin esto, reinicia el daemon desde un shell nuevo cuando empiece a fallar.
- **Precedencia** para transporte y proxy: flag de línea de comandos, luego `$PILOT_TRANSPORT` / `$PILOT_PROXY` / `$PILOT_PROXY_CMD`, luego `config.json` (`transport`, `proxy`, `proxy_cmd`), luego el valor por defecto (`auto` desde pilotctl y los servicios systemd/launchd instalados, vía `PILOT_TRANSPORT_DEFAULT=auto`; `udp` para un `pilot-daemon` sin más; proxy `auto`). `auto` nunca se guarda en config.json, así que reinstalar una versión anterior (`--version`, `pilotctl update --pin`) no deja nada que no pueda leer; si lo guardaste tú mismo, ambos lo reescriben a `udp` para un daemon anterior a él. `-proxy` acepta `auto`, `off` (también `none`, `direct`) o una URL `http://` / `https://`; cualquier otra cosa es un error. Los destinos de loopback (webhooks locales, sidecars) nunca se envían a un proxy. Cuando el dial al registro pasa por un proxy (compat, o una URL de proxy explícita en cualquier transporte), el registro raw-TCP por defecto se sustituye por `registry.pilotprotocol.network:443` sobre TLS, ya que los proxies CONNECT solo llevan el puerto 443.
- **¿No hay CA bundle en el sandbox?** Apunta a uno con `SSL_CERT_FILE=/path/to/ca-certificates.crt` (o `SSL_CERT_DIR`) — `pilotctl daemon start` reenvía ambos. El registro puede en su lugar fijarse: `PILOT_REGISTRY_FINGERPRINT=<sha256 of its certificate>` (o `pilotctl config --set registry_fingerprint=...`), lo que selecciona `registry_trust=pinned`. El beacon WSS no tiene opción de fingerprint, así que necesita el CA bundle.
<details>
<summary><strong>Qué hace el instalador</strong></summary>
- Detecta tu plataforma (linux/darwin, amd64/arm64)
- Descarga binarios precompilados de la última release (recurre a compilar desde el código fuente si Go está disponible)
- Instala `pilot-daemon`, `pilotctl` y `pilot-updater` en `~/.pilot/bin` (los tarballs de release incluyen estos tres; el gateway es un extra opcional, no forma parte de la instalación principal)
- Añade `~/.pilot/bin` a tu PATH
- Escribe `~/.pilot/config.json` con el servidor de rendezvous público preconfigurado
- Configura servicios del sistema (**Linux**: systemd, **macOS**: launchd) para el daemon y el auto-updater
- El auto-updater se ejecuta en segundo plano, comprobando nuevas releases cada hora y aplicando actualizaciones automáticamente
**Desinstalar:** `curl -fsSL https://pilotprotocol.network/install.sh | sh -s uninstall`
**Desde el código fuente** (requiere Go 1.25+): `git clone https://github.com/pilot-protocol/pilotprotocol.git && cd pilotprotocol && make build`
</details>
---
## App Store
Pilot incluye una app store integrada para instalar y llamar apps IPC locales:
```bash
pilotctl appstore catalogue # browse available apps
pilotctl appstore view io.pilot.cosift # inspect before installing
pilotctl appstore install io.pilot.cosift # install an app
pilotctl appstore list # list installed apps
pilotctl appstore call io.pilot.cosift cosift.help '{}' # discover methods + latencies
pilotctl appstore call io.pilot.cosift cosift.search '{"q":"raft consensus","k":"5"}'
```
Las apps están firmadas (ed25519), verificadas al instalar y en cada inicio. El daemon intermedia todas las llamadas entre apps — solo se puede acceder a una app a través de los métodos que declara en su manifiesto. Consulta la [documentación de la App Store](https://pilotprotocol.network/docs/app-store) para crear, firmar y publicar apps.
---
## Testing
```bash
go test -parallel 4 -count=1 ./tests/
```
El flag `-parallel 4` es obligatorio — el paralelismo ilimitado agota los puertos y provoca tiempos de espera de marcado.
---
## Controles de privacidad y consentimiento
Cuatro funciones se incluyen **activadas por defecto**. Cada una mejora Pilot — para ti, para los desarrolladores o para la red — pero cada una conlleva un coste que deberías entender antes de aceptarlo. Ninguna de ellas afecta a la mensajería básica, el enrutamiento ni el cifrado.
Documentación completa, perfiles de riesgo y comandos por función: **[pilotprotocol.network/docs/consent](https://pilotprotocol.network/docs/consent)**
---
### Telemetría — riesgo: bajo
**Qué hace.** Cuando navegas o instalas aplicaciones, se envía un evento firmado (ID de la aplicación + acción) a `telemetry.pilotprotocol.network`.
**A quién ayuda.** Los desarrolladores de aplicaciones obtienen señal sobre lo que realmente se usa; el catálogo destaca aplicaciones de calidad frente a las abandonadas; tú te beneficias de una tienda curada que mejora según el uso real — no según la publicidad.
**Qué estás aceptando.** El servidor de telemetría recibe el ID de la aplicación, el tipo de acción y una firma de tu clave Ed25519 (seudónima a menos que te hayas registrado con `-email`). Tu IP es visible durante la conexión TLS. Nunca se envían contenidos de mensajes ni datos de conversaciones.
**Para desactivarla:**
```json
{"consent": {"telemetry": false}}
```
Se configura en `~/.pilot/config.json`. El cliente de telemetría se convierte en un no-op estricto — sin marcado, sin goroutine. Surte efecto inmediatamente para los comandos de la CLI.
**Quién debería optar por no participar:** Usuarios con políticas estrictas de no telemetría, despliegues de alta sensibilidad o canalizaciones automatizadas donde cualquier telemetría saliente no es deseable.
---
### Broadcasts — riesgo: medio
**Qué hace.** Los administradores de red pueden enviar un único datagrama autenticado a todos los agentes de una red simultáneamente. Tu daemon verifica el token de administrador y reenvía la carga útil a tu agente.
**A quién ayuda.** Los operadores de flotas coordinan todos los agentes en un solo comando — actualizaciones de configuración, reinicios progresivos, respuesta a incidentes — sin O(N) mensajes individuales. El único mecanismo de coordinación O(1) en una gran malla de pares.
**Qué estás aceptando.** Cualquier parte que posea el token de administrador de la red puede entregar datos arbitrarios a tu agente. La seguridad del token es el límite: si se filtra o lo posee alguien en quien no confías, un atacante puede alcanzar tu agente.
**Para optar por no participar:**
```json
{"consent": {"broadcasts": false}}
```
Los datagramas entrantes se descartan silenciosamente antes de llegar a tu agente. Reinicia el daemon para que el cambio surta efecto.
**Quién debería optar por no participar:** Usuarios individuales (sin flota, sin administrador — la función no te ofrece ningún beneficio y estás aceptando una superficie de ataque a cambio de nada). Usuarios que se unen a redes cuyos administradores no conocen o en los que no confían.
---
### Reseñas — riesgo: bajo
**Qué hace.** Después de ~5% de las llamadas a `pilotctl send-message`, aparece un aviso en stderr invitando a dejar una reseña. Después de ~5% de las invocaciones a `pilotctl appstore call`, la salida se reemplaza por un aviso de reseña para esa app. El comando explícito `pilotctl review <subject>` envía una reseña directamente.
**A quién ayuda.** Las reseñas de la comunidad revelan señales de calidad antes de instalar. Los desarrolladores de apps reciben comentarios directos. Las puntuaciones de las reseñas impulsan el ranking del catálogo — las apps buenas obtienen visibilidad, las defectuosas quedan relegadas.
**Qué estás aceptando.** El texto de las reseñas es completamente redactado por el usuario y opcional. El principal riesgo operativo es que la intercepción del 5% corrompa stdout en los scripts.
```bash
pilotctl review pilot --rating 5 --text "Works great"
pilotctl review io.pilot.cosift --rating 4
```
**Para darse de baja:**
```json
{"consent": {"reviews": false}}
```
Sin prompts, sin interceptaciones, sin datos enviados. Surte efecto de inmediato.
**Quién debería desactivarlo:** Usuarios que ejecutan `pilotctl` en automatización o pipelines donde stdout debe estar limpio. Usuarios que no quieren prompts no solicitados durante la operación normal.
---
### Inyección de skills — riesgo: medio
**Qué hace.** El daemon escribe un `SKILL.md` y una directiva de heartbeat en los directorios de configuración de las cadenas de herramientas de agentes compatibles (Claude Code `~/.claude/CLAUDE.md`, Cursor `.cursor/rules`, OpenHands, OpenClaw, Hermes), indicando a esos agentes que recurran a las herramientas de Pilot antes de recurrir a `web_search` o `curl`.
**A quién ayuda.** Obtienes integración sin configuración — los agentes saben automáticamente que Pilot está disponible para mensajería entre pares, consultas a especialistas y llamadas a aplicaciones. La red gana más agentes activos en la malla, enriqueciendo el ecosistema para todos.
**Qué estás aceptando.** El inyector obtiene contenido en tiempo de ejecución desde [`TeoSlayer/pilot-skills`](https://github.com/TeoSlayer/pilot-skills) y lo escribe en el directorio de configuración de tu agente. Si ese repositorio se ve comprometido, el contenido inyectado podría influir en el comportamiento de tu agente. En modo `auto`, las actualizaciones llegan cada 15 minutos sin tu revisión. En modo `manual` (el predeterminado), las actualizaciones solo se aplican cuando ejecutas explícitamente `pilotctl update`.
**Tres modos — elige tu equilibrio entre riesgo y comodidad:**
| Modo | Comportamiento |
|------|----------|
| `manual` *(predeterminado en instalación nueva)* | Instala una vez al iniciar el daemon. Actualiza solo cuando ejecutas `pilotctl update`. |
| `auto` | Reconciliación cada 15 minutos. Siempre actualizado. |
| `disabled` | Sin inyección. Sin actualizaciones. Elimina inmediatamente los archivos inyectados existentes. |
```bash
pilotctl skills status # show mode + managed file paths
pilotctl skills set-mode manual # install once, update on your terms
pilotctl skills set-mode auto # continuous 15-min updates
pilotctl skills set-mode disabled # remove everything, stop all ticks
pilotctl update # force-apply latest skills now (all modes)
```
El modo se almacena en `~/.pilot/config.json` bajo `skill_inject.mode`. Los cambios surten efecto inmediatamente — no se necesita reiniciar.
Todo lo que se inyecta es de código abierto: [`pilot-protocol/skillinject`](https://github.com/pilot-protocol/skillinject) (el inyector), [`TeoSlayer/pilot-skills`](https://github.com/TeoSlayer/pilot-skills) (el contenido).
**Quién debería optar por no participar o usar `manual`:** Usuarios con requisitos estrictos de control de configuración del agente. Usuarios en entornos donde cualquier escritura externa en directorios de configuración es un problema de cumplimiento.
---
### Modo sandbox del daemon
El daemon `pilotd` acepta un flag `-sandbox` que confina todo el acceso al sistema de archivos a un único directorio. Esto no es una característica de privacidad — no cambia qué datos se envían — pero limita el radio de impacto si el daemon se ve comprometido.
```bash
pilotd -sandbox # confine to ~/.pilot (default)
pilotd -sandbox -sandbox-dir /opt/pilot # confine to a custom directory
```
Cualquier ruta pasada explícitamente que se resuelva fuera del directorio sandbox provoca un error fatal al inicio, antes de que el daemon lea o escriba nada. Los flags de ruta no establecidos se redirigen automáticamente dentro del directorio sandbox.
---
### Deshabilitar todo a la vez
```json
{
"consent": {
"telemetry": false,
"broadcasts": false,
"reviews": false
},
"skill_inject": {"mode": "disabled"}
}
```
Se establece en `~/.pilot/config.json` y se reinicia el daemon. La red principal no se ve afectada.
---
## Variables de entorno clave
La mayoría de los flags del daemon tienen una variable de entorno equivalente. Útil para despliegues en contenedores y CI.
| Variable | Flag equivalente | Propósito |
|----------|----------------|---------|
| `PILOT_REGISTRY` | `-registry` | Dirección del servidor de registro |
| `PILOT_BEACON` | `-beacon` | Dirección del servidor beacon |
| `PILOT_TRANSPORT` | `-transport` | Transporte del túnel: `udp` (predeterminado del daemon), `compat` (registro TLS + beacon WSS solo en TCP 443) o `auto` (udp cuando el beacon responde por UDP, si no, compat). Tiene prioridad sobre `config.json` |
| `PILOT_PROXY` | `-proxy` | Proxy de salida: `auto` (predeterminado; con compat, el proxy `HTTPS_PROXY`/`ALL_PROXY` que respeta `NO_PROXY`), `off` (también `none`, `direct`), o `http(s)://[user:pass@]host:port` para cada conexión excepto loopback. Tiene prioridad sobre `config.json` |
| `PILOT_PROXY_CMD` | `-proxy-cmd` | Comando (`sh -c`) que imprime la URL del proxy actual, se vuelve a ejecutar una vez transcurridos 60s y ante un 407 (entonces la conexión se reintenta una vez), para proxies que rotan credenciales; proporciona la URL que usaría `-proxy`. Tiene prioridad sobre `config.json` (`proxy_cmd`) |
| `PILOT_TRANSPORT_DEFAULT` | — | Transporte cuando ni `-transport`, ni `PILOT_TRANSPORT` ni `config.json` establecen uno (los servicios instalados establecen `auto`; los daemons sin `auto` lo ignoran) |
| `PILOT_REGISTRY_TRUST` / `PILOT_REGISTRY_FINGERPRINT` | `-registry-trust` / `-registry-fingerprint` | Fija el registro TLS (hosts sin un bundle de CA); una huella por sí sola selecciona confianza fijada en modo compat. Tienen prioridad sobre `config.json` |
| `HTTPS_PROXY` / `ALL_PROXY` / `NO_PROXY` | — | Proxy usado con `-proxy=auto` en modo compat y por las propias conexiones al registro de `pilotctl`; `pilotctl daemon start` los reenvía (junto con `SSL_CERT_FILE` / `SSL_CERT_DIR`) al daemon |
| `PILOT_SOCKET` | `-socket` | Ruta del socket Unix |
| `PILOT_EMAIL` | `-email` | Correo electrónico de la cuenta |
| `PILOT_HOSTNAME` | `-hostname` | Nombre de host de descubrimiento |
| `PILOT_ADMIN_TOKEN` | `-admin-token` | Token de administrador para operaciones de red |
| `PILOT_MOTD_URL` | `-motd-feed-url` | URL del feed de mensaje del día |
| `PILOT_TELEMETRY_URL` | `-telemetry-url` | Anulación del endpoint de telemetría |
| `PILOT_SYN_WHITELIST` | `-syn-whitelist` | Nodos exentos del límite de tasa de SYN |
| `PILOT_REPLY_WHITELIST` | `-reply-whitelist` | Nodos exentos del límite de tasa de respuestas |
| `PILOT_REKEY_WHITELIST` | `-rekey-whitelist` | Nodos exentos del límite de tasa de rekey |
| `PILOT_FLAG_<NAME>` | — | Anulación de flag de característica (`true`/`false`) |
| `PILOT_APP_UPDATE_OPT_OUT` | — | Excluirse de las actualizaciones automáticas de la **app-store**. Establecido en `true`, el `pilot-updater` deja de buscar e instalar actualizaciones de apps — las apps instaladas permanecen en su versión actual. Sin establecer o en `false` (el valor predeterminado) mantiene activadas las actualizaciones automáticas de apps. Las actualizaciones del binario del daemon/CLI de Pilot no se ven afectadas. Lo lee `pilot-updater` al iniciarse, así que establécelo en el entorno del servicio del updater y reinicia el updater para cambiarlo. (Alias heredado: `PILOT_UPDATER_NO_APP_UPGRADE`.) |
---
## Documentación
| Documento | Descripción |
|----------|-------------|
---
[Read more](https://github.com/pilot-protocol/pilotprotocol)