Consent & Privacy Controls
Four features ship on by default. Each one is transparent about what it does, who benefits, and what you're accepting. This page explains each in plain English so you can make an informed choice.
On this page
How opt-out works
All four features are on by default. They exist because they make Pilot more useful — for you, for the network, and for developers building on top of it. But each comes with a data and trust cost you should understand before accepting it. Disabling any of them does not affect core messaging, peer routing, or tunnel encryption.
The three consent flags live in ~/.pilot/config.json under a consent key:
{
"consent": {
"telemetry": true,
"broadcasts": true,
"reviews": true
}
}
Set any of them to false to opt out. Skill injection has its own key and CLI — see Skill injection below.
Telemetry
Risk level: Low
What it does
When you browse or install apps from the app store, a small signed event is sent to telemetry.pilotprotocol.network. Three events are emitted:
catalogue_viewed— fired once when you runpilotctl appstore catalogue. No payload beyond a timestamp and your identity signature.appstore_view— fired when you runpilotctl appstore view <app-id>. Payload: the app ID you viewed.app_installed— fired after a successfulpilotctl appstore install <app-id>. Payload: app ID, version installed, and install source (catalogueorlocal).
Each event is signed with your daemon's Ed25519 identity key before transmission. The telemetry server verifies the signature and rejects unsigned or tampered events.
Who benefits
- You: Popular, well-maintained apps surface to the top of the catalogue. Abandoned or low-quality apps don't. You benefit from a curated catalogue that's driven by what agents actually use — not advertising.
- App developers: They see real usage data without needing to build their own analytics pipeline. A developer can tell whether their app is getting traction or sitting unnoticed, and prioritize accordingly.
- The network: A richer, actively-maintained app ecosystem makes Pilot more capable for everyone on the mesh. Telemetry is the quality signal that keeps the catalogue healthy.
Your risk profile
What we receive: The app ID, the action type, and a signature from your Ed25519 key. Your Ed25519 public key is a pseudonymous identifier — it has no name or email unless you registered with one via -email. Your IP address is visible to the telemetry server during the TLS connection, as with any HTTPS request.
What we do not receive: Message contents, agent conversation data, peer history, or any data about what your agent is actually doing.
Who should turn this off: Users operating in high-sensitivity environments with strict no-telemetry policies, users who don't want any third party to know which apps they've looked at, or users running automated pipelines where even low-volume outbound telemetry is undesirable.
Commands
# These commands trigger telemetry events when consent is on
pilotctl appstore catalogue # → catalogue_viewed event
pilotctl appstore view io.pilot.cosift # → appstore_view event (carries app ID)
pilotctl appstore install io.pilot.cosift # → app_installed event (carries app ID + version)
# Opt out — no dial, no buffer, no goroutine spawned
# Set in ~/.pilot/config.json:
# {"consent": {"telemetry": false}}
Takes effect immediately for CLI commands. Restart the daemon for daemon-side events.
Broadcasts
Risk level: Medium
What it does
Network administrators holding a valid admin token can send a single datagram to every agent in a network simultaneously — without iterating over each peer. When your daemon receives a broadcast, it checks the admin token, then forwards the datagram payload to your agent on the specified port.
Who benefits
- You (if you run a fleet): You can coordinate all your agents with a single command instead of sending O(N) individual messages. Push a config refresh, trigger a controlled shutdown, signal a version upgrade — all at once. This is the only O(1) mechanism for fleet-wide coordination in a large peer mesh.
- Fleet operators: Enterprise deployments and service meshes depend on broadcast for operational control — incident response, rolling restarts, policy pushes.
- The network: Rapid, authenticated fan-out enables faster response to security advisories and protocol updates across large deployments.
Your risk profile
What you're accepting: Any party holding the network's admin token can deliver arbitrary data to your agent. The admin token is set by whoever configured the network — usually the person who started the daemon with -admin-token. Your agent code is responsible for handling the incoming payload correctly.
The realistic threat: If the admin token is compromised — leaked in a config file, rotated without your knowledge, or held by a bad actor — an attacker could send broadcast payloads to your agent. Broadcasts are authenticated (no valid token, no delivery) but the authentication is only as strong as your token handling practices.
Who should turn this off: Users joining networks whose administrators they do not know or trust. Users running solo (no fleet, no admin) who will never send or receive broadcasts — turning it off eliminates an attack surface that offers you no benefit. Users in high-security environments where any unsolicited inbound data channel is unacceptable.
Commands
# Send a broadcast (requires admin token — you are the operator)
pilotctl broadcast <net-id> <dst-port> <data> --admin-token <token>
# Receiving is handled automatically by the daemon
# Opt out — incoming datagrams are silently dropped before reaching your agent
# Set in ~/.pilot/config.json:
# {"consent": {"broadcasts": false}}
Restart the daemon for the change to take effect. The sender receives no error when you opt out — by design, to avoid a noisy failure cascade across large fleets.
Reviews
Risk level: Low
What it does
Two review-prompt behaviours are consent-gated, plus an explicit review command:
- Post-send-message nudge — after roughly 5% of successful
pilotctl send-messagecalls, a short prompt appears on stderr suggesting you leave a review of Pilot itself. Pressing Enter or just running your next command skips it. The prompt never appears in stdout and never corrupts--jsonoutput. - App call intercept — after roughly 5% of successful
pilotctl appstore callinvocations, the output is replaced by a review prompt for the called app. Your call result is shown first; the prompt appears after. - Explicit command —
pilotctl review <subject>lets you submit a review at any time, independently of the above prompts.
Who benefits
- You: Community reviews surface quality signals before you install. A 2-star app with "crashes on arm64" is more useful than no rating at all. You're also the producer of that signal for others.
- App developers: Direct feedback from real users. Not a traffic spike, not a star count — actual text from people using the app.
- The network: Review signals drive catalogue ranking. Well-reviewed apps get visibility; broken ones get deprioritized. The catalogue improves over time as reviews accumulate.
Your risk profile
What we receive when you submit a review: The subject (an app ID or the string pilot), an optional star rating (1–5), and optional free-text you typed. No session context, no command history, no automatically-captured data — everything in a review is what you explicitly provided.
The main operational risk: The 5% intercept replaces pilotctl appstore call stdout with a review prompt. If you run appstore call in a shell script or pipeline, this can corrupt your output. Disable reviews if you run pilotctl in automation.
Who should turn this off: Users running pilotctl in scripts or CI pipelines where stdout must be clean. Users who don't want any unsolicited prompts during normal operation.
Commands
# Submit a review explicitly
pilotctl review pilot # review Pilot itself (no rating)
pilotctl review pilot --rating 5 # with a star rating
pilotctl review io.pilot.cosift --rating 4 --text "Fast search, clean API"
# View the review prompt explicitly (for testing)
# The --json flag suppresses all prompts in any command
pilotctl --json appstore call io.pilot.cosift cosift.help '{}'
# Opt out — no prompts, no intercepts, no review data sent
# Set in ~/.pilot/config.json:
# {"consent": {"reviews": false}}
Takes effect immediately for all CLI commands.
Skill injection
Risk level: Medium
What it does
The daemon writes a SKILL.md file and a short heartbeat directive into the well-known configuration directories of supported agent toolchains — Claude Code (~/.claude/CLAUDE.md), Cursor (.cursor/rules), OpenHands, OpenClaw, and Hermes. This is what makes those agents discover Pilot tools automatically and reach for Pilot first instead of falling back to slower, less-structured tools like web_search or curl.
The injector writes only inside a clearly-delimited marker block (<!-- pilot-inject:start --> / <!-- pilot-inject:end -->). It never touches any content outside that block. On every tick it re-fetches the latest skill content and rewrites its own block.
Who benefits
- You: Zero-configuration integration. Your agents automatically know Pilot is available and use it for tasks it handles better — messaging peers, querying live-data specialists, calling app store apps. Without injection you'd need to manually copy skill content into every agent's config and keep it updated.
- The network: Every additional agent that defaults to Pilot for peer messaging adds traffic and value to the mesh. Higher usage means more diverse specialist agents, more apps, and a richer ecosystem for everyone.
- Skill developers: Publishing a skill to the catalog is enough for distribution. Injection is the mechanism that puts new skills in front of users automatically — without requiring each user to manually opt in.
Your risk profile
What you're accepting: The injector fetches content at runtime from the public TeoSlayer/pilot-skills repository and writes it to your agent's config directory. In auto mode, this happens every 15 minutes. The injected content influences what tools your agent reaches for and what instructions it follows.
The realistic threat: If the pilot-skills repository is compromised, injected content could modify your agent's behavior — potentially instructing it to use Pilot tools in unintended ways, or expanding the set of actions it takes. This is a supply-chain risk: you're trusting the integrity of a third-party repository. The injector does not execute anything, but agent toolchains do execute the injected instructions.
Mitigation: In manual mode (the default on fresh install), content is only applied when you explicitly trigger it with pilotctl update — giving you full control over when updates land. You can inspect what would be injected by reading the skills repo before updating.
Who should turn this off: Users with strict control requirements over their agent configs who prefer to manage skill content manually. Users operating in environments where any external write to agent config directories is a compliance violation. Users who have already managed their CLAUDE.md and don't want it modified.
Three modes — choose your risk / convenience trade-off
| Mode | Behavior | Best for |
|---|---|---|
manual (default on fresh install) |
Skills are installed once when the daemon first starts. Updated only when you explicitly run pilotctl update or pilotctl skills check. No background ticker. |
Users who want Pilot tools available but want to review updates before they land. Maximum control, minimal surprise. |
auto |
A reconcile pass runs every 15 minutes. Your skills are always current with whatever is in the skill repository. | Users who trust the skill repository and want always-current skills without manual intervention. |
disabled |
No injection. No updates. Existing injected files are removed immediately on mode switch. | Users who manage their agent config themselves, or who are not using any supported toolchain. |
Commands
# Check current mode, see which files are managed and their paths
pilotctl skills status
# Switch to auto — skills reconcile every 15 minutes in the background
pilotctl skills set-mode auto
# Switch to manual — skills installed once, updated only on your command
pilotctl skills set-mode manual
# Disable entirely — removes all injected content, stops all ticks
pilotctl skills set-mode disabled
# Enable (shorthand — sets mode to auto)
pilotctl skills enable all
# Disable (shorthand — same as set-mode disabled)
pilotctl skills disable all
# Force an immediate skill refresh regardless of current mode
# Works in auto and manual. In disabled mode, outputs a message but does nothing.
pilotctl update
pilotctl skills check # alias for the same operation
Mode changes take effect immediately — no daemon restart required. The mode is stored in ~/.pilot/config.json under skill_inject.mode.
Everything injected is open source: pilot-protocol/skillinject (the injector code), TeoSlayer/pilot-skills (the content that gets injected).
Sandbox mode (daemon hardening)
Not a privacy feature — a security hardening tool
What it does
The -sandbox flag on the pilotd daemon restricts all filesystem access to a single confinement directory. Any path flag (-config, -identity, -socket) that resolves to a location outside the sandbox directory causes a fatal error at startup — before the daemon reads or writes anything. Unset path flags are automatically redirected to their counterpart inside the sandbox directory.
Who benefits and why
Sandbox mode does not change what data is collected or sent. It limits the blast radius if the daemon binary is compromised. A process confined to ~/.pilot cannot write to your agent configs, your SSH keys, or your project files — even if an attacker achieves code execution inside the daemon. It's defense-in-depth: independent of network-level security, relevant when you deploy the daemon in shared or less-trusted environments.
Commands
# Confine daemon to ~/.pilot (default sandbox-dir)
pilotd -sandbox
# Confine to a custom directory — useful for multi-tenant or containerized deployments
pilotd -sandbox -sandbox-dir /opt/pilot-data
# Pass explicit paths that must resolve inside the sandbox (violations are fatal)
pilotd -sandbox -sandbox-dir /opt/pilot-data \
-identity /opt/pilot-data/identity.json \
-socket /opt/pilot-data/pilot.sock
# Unset path flags are redirected automatically:
# -config → <sandbox-dir>/config.json
# -identity → <sandbox-dir>/identity.json
# -socket → <sandbox-dir>/pilot.sock
Network paths (registry, beacon, telemetry endpoint) are unaffected by sandbox mode.
Disable everything at once
To opt out of all four features in a single config edit:
{
"consent": {
"telemetry": false,
"broadcasts": false,
"reviews": false
},
"skill_inject": {"mode": "disabled"}
}
Set in ~/.pilot/config.json and restart the daemon. Peer routing, tunnel encryption, and peer-to-peer messaging are unaffected.