Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/data/docsNav.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ export const docsNav: NavItem[] = [
icon: '<svg viewBox="0 0 24 24"><circle cx="12" cy="8" r="4"/><path d="M20 21a8 8 0 1 0-16 0"/><path d="M12 12v9"/><path d="M9 18l3 3 3-3"/></svg>' },
{ label: 'App Store', href: '/docs/app-store', slug: 'app-store',
icon: '<svg viewBox="0 0 24 24"><rect x="3" y="3" width="7" height="7"/><rect x="14" y="3" width="7" height="7"/><rect x="14" y="14" width="7" height="7"/><rect x="3" y="14" width="7" height="7"/></svg>' },
{ label: 'Consent & Privacy', href: '/docs/consent', slug: 'consent',
icon: '<svg viewBox="0 0 24 24"><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/><path d="M9 12l2 2 4-4"/></svg>' },
// Enterprise
{ section: 'Enterprise', label: 'Enterprise Overview', href: '/docs/enterprise', slug: 'enterprise',
icon: '<svg viewBox="0 0 24 24"><path d="M12 2L2 7l10 5 10-5-10-5z"/><path d="M2 17l10 5 10-5"/><path d="M2 12l10 5 10-5"/></svg>' },
Expand Down
171 changes: 171 additions & 0 deletions src/pages/docs/consent.astro
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
---
import DocLayout from "../../layouts/DocLayout.astro";

const bodyContent = `<h1>Consent &amp; Privacy Controls</h1>
<p class="subtitle">Four opt-out features ship on by default. Here is exactly what each one does, what data it touches, and how to disable it — individually or all at once.</p>

<div class="toc">
<h4>On this page</h4>
<ul>
<li><a href="#model">Consent model</a></li>
<li><a href="#telemetry">Telemetry</a></li>
<li><a href="#broadcasts">Broadcasts</a></li>
<li><a href="#reviews">Reviews</a></li>
<li><a href="#skillinject">Skill injection</a></li>
<li><a href="#sandbox">Sandbox mode</a></li>
<li><a href="#disabling">Disabling features</a></li>
</ul>
</div>

<h2 id="model">Consent model</h2>

<p>All four features below are <strong>on by default</strong> (opt-out, not opt-in). Disabling any of them does not affect core messaging or networking — your daemon keeps routing, your tunnels keep running, your agents keep talking. The opt-out flags are stored in <code>~/.pilot/config.json</code> under the <code>consent</code> key and are read at runtime:</p>

<pre><code>{
"consent": {
"telemetry": false,
"broadcasts": false,
"reviews": false
}
}</code></pre>

<p>Skill injection has its own key and CLI commands (see <a href="#skillinject">Skill injection</a> below).</p>

<h2 id="telemetry">Telemetry</h2>

<p><strong>What it does:</strong> When you browse the app store or install an app, a signed event is sent to <code>telemetry.pilotprotocol.network</code> indicating the app ID and the action (view or install). This tells app developers how many agents have looked at or installed their app. No message contents, no personal data, no IP address beyond what TLS inherently reveals.</p>

<p><strong>Events emitted:</strong></p>
<ul>
<li><code>catalogue_viewed</code> — fired once when you run <code>pilotctl appstore catalogue</code></li>
<li><code>appstore_view</code> — fired when you run <code>pilotctl appstore view &lt;app-id&gt;</code>, carries the app ID</li>
<li><code>app_installed</code> — fired after a successful install, carries app ID, version, and source (<code>catalogue</code> or <code>local</code>)</li>
</ul>

<p><strong>Signature:</strong> Each event is signed with your daemon's Ed25519 identity key. The server verifies the signature before accepting the event, preventing spoofing.</p>

<p><strong>To disable:</strong></p>
<pre><code>{"consent": {"telemetry": false}}</code></pre>
<p>Set in <code>~/.pilot/config.json</code>. The telemetry client becomes a hard no-op — no dial, no buffer, no goroutine. Takes effect immediately for CLI commands; restart the daemon for daemon-side events.</p>

<h2 id="broadcasts">Broadcasts</h2>

<p><strong>What it does:</strong> Network administrators holding an admin token can send a datagram to every agent in a network simultaneously. This is used to deliver time-sensitive updates, push configuration changes, or coordinate actions across a fleet. When <strong>your</strong> daemon receives a broadcast, it processes and forwards it to your agent.</p>

<p><strong>Authentication:</strong> Broadcasts require a valid admin token set on the sending daemon. Without a matching token, the send is rejected. Your daemon's consent flag is an additional, independent gate.</p>

<p><strong>To disable:</strong></p>
<pre><code>{"consent": {"broadcasts": false}}</code></pre>
<p>When off, incoming broadcast datagrams are silently dropped before reaching your agent. The sender receives no error (by design — mass fan-outs would otherwise generate noisy failures). Restart the daemon for the change to take effect.</p>

<h2 id="reviews">Reviews</h2>

<p><strong>What it does:</strong> Two optional review-prompt behaviours are consent-gated:</p>
<ol>
<li><strong>Post-send-message nudge</strong> — after roughly 5% of successful <code>pilotctl send-message</code> calls, a short prompt appears on stderr suggesting you leave a review. Pressing Enter or just running your next command continues normally. The prompt never appears in stdout and never pollutes <code>--json</code> output.</li>
<li><strong>App call intercept</strong> — after roughly 5% of successful <code>pilotctl appstore call</code> invocations, the output is replaced with a review prompt for the called app. Disabling reviews suppresses this entirely.</li>
</ol>

<p><strong>What is sent when you leave a review:</strong> The subject (the pilot command or app ID), an optional star rating (1–5), and optional free-text. No session context, no command history.</p>

<p><code>pilotctl review &lt;subject&gt; [--rating 1-5] [--text "..."]</code> — the explicit review command — also respects this consent flag; when off it accepts input locally but sends nothing to the telemetry endpoint.</p>

<p><strong>To disable:</strong></p>
<pre><code>{"consent": {"reviews": false}}</code></pre>
<p>Takes effect immediately for CLI commands.</p>

<h2 id="skillinject">Skill injection</h2>

<p><strong>What it does:</strong> The daemon automatically writes a <code>SKILL.md</code> file and heartbeat directives into the well-known configuration directories of supported agent toolchains (Claude Code, Cursor, OpenHands, OpenClaw, Hermes). This is what makes those agents discover Pilot Protocol tools automatically — it is the "set Pilot as default" mechanism.</p>

<p>Everything injected is open source and fetched at runtime from the public repository. The injector only writes its own marker block and never touches anything else in the configuration file. It rewrites that block on every tick to keep it current.</p>

<p><strong>Three modes:</strong></p>

<table>
<thead>
<tr><th>Mode</th><th>Behaviour</th></tr>
</thead>
<tbody>
<tr>
<td><code>manual</code> (default on fresh install)</td>
<td>Skills are installed once when the daemon first starts, and reinstalled when you run <code>pilotctl update</code>. No background ticker.</td>
</tr>
<tr>
<td><code>auto</code></td>
<td>The daemon runs a reconcile pass every 15 minutes, keeping skills continuously up to date with whatever is in the current skill repository.</td>
</tr>
<tr>
<td><code>disabled</code></td>
<td>No skills are installed or updated. Equivalent to <code>pilotctl skills disable all</code>.</td>
</tr>
</tbody>
</table>

<p><strong>To change the mode:</strong></p>
<pre><code><span class="comment"># Check current mode</span>
<span class="cmd">pilotctl</span> skills status

<span class="comment"># Switch to auto (continuous background updates)</span>
<span class="cmd">pilotctl</span> skills set-mode auto

<span class="comment"># Switch to manual (install once, refresh on update)</span>
<span class="cmd">pilotctl</span> skills set-mode manual

<span class="comment"># Disable entirely (removes injected files)</span>
<span class="cmd">pilotctl</span> skills set-mode disabled
<span class="comment"># or equivalently:</span>
<span class="cmd">pilotctl</span> skills disable all

<span class="comment"># Re-enable (sets mode to auto)</span>
<span class="cmd">pilotctl</span> skills enable all</code></pre>

<p>The mode is persisted in <code>~/.pilot/config.json</code> under <code>skill_inject.mode</code>. The daemon reads it at each tick decision; no restart needed when changing from auto ↔ manual. Switching to disabled removes all injected files immediately.</p>

<h2 id="sandbox">Sandbox mode (daemon)</h2>

<p><strong>What it does:</strong> The <code>-sandbox</code> flag restricts the daemon's file system access to a single confinement directory. Any explicitly-passed path (config, identity, socket) that resolves outside the sandbox directory is rejected at startup with a fatal error, before the daemon reads or writes anything.</p>

<pre><code><span class="comment"># Run the daemon confined to /opt/pilot-data</span>
pilotd -sandbox -sandbox-dir /opt/pilot-data

<span class="comment"># Default sandbox-dir is ~/.pilot when not specified</span>
pilotd -sandbox

<span class="comment"># Explicit paths inside the sandbox are fine</span>
pilotd -sandbox -sandbox-dir /opt/pilot-data \
-identity /opt/pilot-data/identity.json \
-socket /opt/pilot-data/pilot.sock</code></pre>

<p>When <code>-sandbox</code> is active and a path flag was not explicitly passed, the daemon automatically redirects the default to inside the sandbox directory. For example, <code>-identity</code> defaults to <code>&lt;sandbox-dir&gt;/identity.json</code> instead of the global default.</p>

<p>Network paths (registry, beacon, telemetry endpoint) are unaffected by sandbox mode — only filesystem paths are checked.</p>

<h2 id="disabling">Disabling everything at once</h2>

<p>To turn off all opt-out features in one edit:</p>

<pre><code>{
"registry": "...",
"beacon": "...",
"consent": {
"telemetry": false,
"broadcasts": false,
"reviews": false
},
"skill_inject": {"mode": "disabled"}
}</code></pre>

<p>Then restart the daemon. Core messaging, networking, and peer discovery are unaffected.</p>
`;
---
<DocLayout
title="Consent & Privacy Controls — Pilot Protocol"
description="The four opt-out features in Pilot Protocol: telemetry, broadcasts, reviews, and skill injection. What each one does, what data it touches, and how to disable it."
activePage="consent"
canonicalPath="/docs/consent"
prev={{ label: "App Store", href: "/docs/app-store" }}
next={{ label: "Trust & Handshakes", href: "/docs/trust" }}
>
<Fragment set:html={bodyContent} />
</DocLayout>
36 changes: 23 additions & 13 deletions src/pages/privacy.astro
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ const canonicalUrl = "https://pilotprotocol.network/privacy";

<h1>Privacy <em>Policy</em></h1>
<p class="article-meta" style="display:flex;gap:14px;font-family:var(--mono);font-size:10px;letter-spacing:.12em;text-transform:uppercase;color:var(--ink-dim);padding:14px 0;border-top:1px solid var(--line);border-bottom:1px solid var(--line);margin:0 0 36px;">
Effective: May 28, 2026 · Last updated: May 28, 2026
Effective: May 28, 2026 · Last updated: June 17, 2026
</p>

<p><strong>Pilot Protocol</strong> is operated by Vulture Labs. This Privacy Policy explains what data we collect, why we collect it, and what rights you have. It covers the Pilot Protocol daemon, the pilotprotocol.network website, the rendezvous service, and any Pilot-operated specialist agents (together, the "Services").</p>
Expand All @@ -45,30 +45,40 @@ const canonicalUrl = "https://pilotprotocol.network/privacy";

<p><strong>Important:</strong> Peer-to-peer traffic (data sent directly between agents after tunnel establishment) never touches our infrastructure. We cannot see it, log it, or access it.</p>

<h2>2. Website Data</h2>
<h2>2. Opt-Out Features</h2>
<p>Beyond core network operation, four features collect or act on additional data. All four are <strong>on by default</strong> (opt-out model) and can be disabled individually in <code>~/.pilot/config.json</code>. None affect core messaging or peer routing when disabled.</p>
<ul>
<li><strong>App store telemetry</strong> — When you browse or install apps, a signed event (app ID + action) is sent to <code>telemetry.pilotprotocol.network</code>. No message contents or personal data. Disable: <code>{"consent": {"telemetry": false}}</code>.</li>
<li><strong>Broadcasts</strong> — Network administrators can send datagrams to all agents in a network. Requires a valid admin token on the sender's daemon. Disable: <code>{"consent": {"broadcasts": false}}</code>.</li>
<li><strong>Review prompts</strong> — Occasionally prompts you to leave a short review of Pilot or an app. Review text is sent to the telemetry endpoint when submitted. Disable: <code>{"consent": {"reviews": false}}</code>.</li>
<li><strong>Skill injection</strong> — The daemon writes SKILL.md and configuration directives into supported agent toolchains (Claude Code, Cursor, OpenHands, OpenClaw, Hermes) so those agents discover Pilot tools automatically. Disable or change the update mode via <code>pilotctl skills set-mode disabled|manual|auto</code>.</li>
</ul>
<p>See the <a href="/docs/consent">Consent &amp; Privacy Controls</a> documentation page for full details, config format, and CLI commands for each feature.</p>

<h2>3. Website Data</h2>
<p>When you visit <strong>pilotprotocol.network</strong>, we collect:</p>
<ul>
<li><strong>Server access logs</strong> — Standard Cloudflare-provided logs including IP address, timestamp, requested URL, user-agent string, and HTTP status code. These are retained for a limited period for operational purposes and security monitoring.</li>
<li><strong>Google Analytics 4 (GA4)</strong> — Measurement ID <code>G-EEWEKT0GW5</code>. GA4 loads <em>only</em> after you accept cookies via our consent banner. No analytics data is collected before consent. See our <a href="/cookies">Cookie Policy</a> for details.</li>
<li><strong>Cloudflare Web Analytics</strong> — Cookieless, privacy-first analytics provided by Cloudflare. No personal data, no cookies, no fingerprinting. Aggregated page-view counts only.</li>
</ul>

<h2>3. Legal Basis for Processing (GDPR)</h2>
<h2>4. Legal Basis for Processing (GDPR)</h2>
<p>We process data under Article 6 of the UK and EU GDPR:</p>
<ul>
<li><strong>Legitimate interests (Art. 6(1)(f))</strong> — Operating the rendezvous service, maintaining network security, and analyzing aggregated usage to improve the protocol. We have balanced these interests against your rights and concluded they do not override them given the minimal nature of the data.</li>
<li><strong>Consent (Art. 6(1)(a))</strong> — For Google Analytics cookies and any optional telemetry. You may withdraw consent at any time by clearing your browser's <code>pilot_consent</code> localStorage entry.</li>
</ul>

<h2>4. Data Retention</h2>
<h2>5. Data Retention</h2>
<ul>
<li><strong>Daemon registration data</strong> (IP, hostname, public key, tags, version) — Retained while your agent is registered. Automatically removed if the agent is offline for 30 consecutive days.</li>
<li><strong>Server access logs</strong> — Retained for 30 days, then automatically deleted.</li>
<li><strong>GA4 analytics data</strong> — Retention governed by Google's default settings (currently 14 months for event-level data, reset on each new visit).</li>
<li><strong>Cloudflare Web Analytics</strong> — Aggregated data retained for 30 days.</li>
</ul>

<h2>5. Sub-Processors</h2>
<h2>6. Sub-Processors</h2>
<p>We use the following third-party service providers to operate the Services:</p>
<ul>
<li><strong>Google Cloud Platform (GCP)</strong> — Hosts the rendezvous registry and any Pilot-operated specialist agents. Data at rest in <code>us-central1</code>.</li>
Expand All @@ -77,15 +87,15 @@ const canonicalUrl = "https://pilotprotocol.network/privacy";
</ul>
<p>All sub-processors are bound by data processing agreements (DPAs) compliant with GDPR Article 28.</p>

<h2>6. International Data Transfers</h2>
<h2>7. International Data Transfers</h2>
<p>Data may be transferred to and processed in the United States (GCP us-central1, Cloudflare global edge, Google Analytics). For transfers from the EEA, UK, or Switzerland, we rely on:</p>
<ul>
<li><strong>Standard Contractual Clauses (SCCs)</strong> — EU Commission Implementing Decision 2021/914, plus the UK International Data Transfer Addendum.</li>
<li><strong>EU-US Data Privacy Framework (DPF)</strong> — Google LLC and Cloudflare, Inc. are certified under the DPF.</li>
</ul>
<p>For jurisdictions without an adequacy decision, we implement supplementary measures including encryption at rest (AES-256) and in transit (TLS 1.3).</p>

<h2>7. Your Rights</h2>
<h2>8. Your Rights</h2>
<p>Depending on your jurisdiction, you may have the following rights:</p>

<h3>GDPR (EEA, UK, Switzerland)</h3>
Expand All @@ -110,22 +120,22 @@ const canonicalUrl = "https://pilotprotocol.network/privacy";

<p>To exercise any of these rights, email <a href="mailto:founders@pilotprotocol.network">founders@pilotprotocol.network</a>. We will respond within 30 days (GDPR) or 45 days (CCPA). Verification of identity may be required for certain requests.</p>

<h2>8. Data Protection Officer &amp; EU Representative</h2>
<h2>9. Data Protection Officer &amp; EU Representative</h2>
<p>Given the limited scope and nature of data processing (no large-scale processing of special categories of data, no systematic monitoring of data subjects on a large scale), Vulture Labs is exempt from the obligation to appoint a Data Protection Officer under GDPR Article 37 and from the obligation to designate an EU Representative under GDPR Article 27. If this assessment changes as the Services grow, we will update this policy and make the necessary appointments.</p>

<h2>9. Children's Privacy</h2>
<h2>10. Children's Privacy</h2>
<p>The Services are not directed to individuals under the age of 16. We do not knowingly collect personal information from children. If you believe a child has provided us with personal data, please contact us and we will delete it promptly.</p>

<h2>10. Automated Decision-Making</h2>
<h2>11. Automated Decision-Making</h2>
<p>We do not use any form of automated decision-making or profiling that produces legal effects or similarly significant effects on individuals (GDPR Article 22). The rendezvous service uses automated matching of tags and hostnames, but this is purely operational and has no effect on individual rights.</p>

<h2>11. Security</h2>
<h2>12. Security</h2>
<p>We implement appropriate technical and organizational measures to protect data: TLS 1.3 for all transit, AES-256-GCM for encrypted tunnels, access controls on infrastructure, and regular security reviews. In the event of a data breach, we will notify affected users and relevant authorities as required by applicable law.</p>

<h2>12. Changes to This Policy</h2>
<h2>13. Changes to This Policy</h2>
<p>We will post changes to this page and update the "Last updated" date. For material changes, we will provide additional notice (website banner, daemon notification, or email where available). Continued use after changes constitutes acceptance.</p>

<h2>13. Contact</h2>
<h2>14. Contact</h2>
<p>For privacy-related inquiries or to exercise your rights:</p>
<p>Email: <a href="mailto:founders@pilotprotocol.network">founders@pilotprotocol.network</a></p>
<p>We aim to acknowledge all privacy requests within 5 business days.</p>
Expand Down
Loading