From 18ade06fa981048613f510a4103b8d2aef720ff9 Mon Sep 17 00:00:00 2001 From: Teodor Calin Date: Fri, 10 Jul 2026 12:59:49 +0300 Subject: [PATCH 01/75] Sweep 4: fix every validated inconsistency site-wide Product-truth fixes (verified against web4 source + module caches): - consent/getting-started/security/privacy: skill-inject toolchains corrected (no Cursor; add PicoClaw), real marker block (pilot:begin/end), auto is the fresh-install default (GetMode returns ModeAuto when key absent), real broadcast signature, pilotd -> pilot-daemon - go-sdk: SDK actually lives at github.com/pilot-protocol/common/driver - configuration: PILOT_RC is the edge-channel flag, add -registry-trust row, unpin --pin example, drop unverifiable "hourly" updater interval - cli-reference: add sign-request/verify-request, network admin subcommands (create/delete/rename/promote/demote/kick/role/policy), skills set-mode Dead links (all curl-verified 404s): - research/python-sdk/firewalls: repo paths that don't exist publicly - PlainLayout footer skills.json -> live TeoSlayer URL - blog: 14 IETF draft-00 links -> -01, phantom-post retargets, org-typo openclaw link, 12 dead externals unlinked, A2A -> a2a-protocol.org Stale commands (source-verified): - blog: 10x pilotctl gateway -> extras gateway; invented syntaxes replaced (search->member-tags get, port-policy->network policy, events->publish/ subscribe, data send/recv->send-file/recv, create-network->network create) Honesty/consistency: - index: spec-valid address, IETF "Spec/Submitted" not "Standard", live +N app badge, no-central-dependency -> direct-data-path framing, unattributed quote and "surveyed" framing removed, two-paths reflects auto default - p2p: "no server in the data path" (matches its own FAQ), bench note - compatibility: stale v1.10.3 pins removed, last-verified stamp added - press: Google Fonts removed (GDPR, PILOT-175 self-hosting) - publish: AGREEMENT_VERSION synced to 2026-07-06 agreement - legal: entity unified to Vulture Labs, Inc. (Delaware) - nav: App Store top-level, Tech dropdown active state, tracking targets - docs: /docs/tags into docsNav + chain, dead DocFooter removed, networks early-access caveat, network-9 explainer, registry/beacon/rendezvous glossary, setups empty-fetch fallback, blogPosts orphan entry removed Co-Authored-By: Claude Fable 5 --- src/components/Nav.astro | 9 +++--- src/data/app-overrides.json | 1 - src/data/blogPosts.json | 14 ---------- src/data/docsNav.ts | 2 ++ src/layouts/PlainLayout.astro | 3 +- src/pages/app-store.astro | 2 +- src/pages/apps/[id].astro | 2 +- .../a2a-agent-cards-over-pilot-tunnels.astro | 2 +- ...ommunication-security-best-practices.astro | 2 +- ...ing-challenges-decentralized-systems.astro | 4 +-- ...ng-terminology-a2a-mcp-anp-protocols.astro | 2 +- ...mous-agent-networking-distributed-ai.astro | 2 +- ...uilding-custom-pilot-skills-openclaw.astro | 8 +++--- ...b-to-live-network-openclaw-discovery.astro | 2 +- ...rking-p2p-solutions-ai-architectures.astro | 2 +- ...xchange-for-decentralized-ai-systems.astro | 8 +++--- ...-secure-ai-systems-a-practical-guide.astro | 4 +-- ...se-phase-3-rbac-policies-audit-fleet.astro | 3 -- ...26-agents-autonomously-adopted-pilot.astro | 2 +- ...ures-decentralized-ai-agent-networks.astro | 6 ++-- ...http-services-over-encrypted-overlay.astro | 16 +++++------ .../ietf-internet-draft-pilot-protocol.astro | 2 +- ...ntegration-for-secure-distributed-ai.astro | 4 +-- ...pipelines-openclaw-encrypted-tunnels.astro | 6 ++-- ...-networking-decentralized-ai-systems.astro | 4 +-- ...r-multi-agent-systems-key-strategies.astro | 6 ++-- ...cure-communication-autonomous-agents.astro | 2 +- .../blog/openanp-ai-alternatives-6.astro | 4 +-- ...s-pilot-agent-networking-one-command.astro | 16 +++++------ ...ure-ai-agent-communication-explained.astro | 2 +- ...trategies-for-distributed-ai-systems.astro | 6 ++-- ...esses-distributed-autonomous-systems.astro | 6 ++-- ...network-addressing-secure-ai-systems.astro | 2 +- ...l-attachment-ai-networks-trust-graph.astro | 2 +- .../blog/private-agent-network-company.astro | 19 +++++-------- ...pping-secure-peer-to-peer-ai-systems.astro | 2 +- .../blog/python-sdk-pilot-protocol.astro | 2 +- ...c-active-research-ready-intelligence.astro | 2 +- ...re-ai-agent-communication-zero-trust.astro | 2 +- ...nt-networks-multi-cloud-environments.astro | 4 +-- ...ddresses-for-secure-decentralized-ai.astro | 4 +-- ...tocol-overlay-fundamentals-practical.astro | 2 +- .../why-ai-agents-need-network-stack.astro | 2 +- ...nnections-power-secure-ai-networking.astro | 4 +-- ...p2p-connections-matter-for-ai-agents.astro | 2 +- ...dependency-encryption-x25519-aes-gcm.astro | 2 +- src/pages/docs/app-store.astro | 2 +- src/pages/docs/cli-reference.astro | 27 ++++++++++++++++-- src/pages/docs/concepts.astro | 2 +- src/pages/docs/configuration.astro | 7 +++-- src/pages/docs/consent.astro | 22 +++++++-------- src/pages/docs/firewalls.astro | 2 +- src/pages/docs/gateway.astro | 2 +- src/pages/docs/getting-started.astro | 5 ++-- src/pages/docs/go-sdk.astro | 10 +++---- src/pages/docs/networks.astro | 1 + src/pages/docs/pilot-director.astro | 2 +- src/pages/docs/python-sdk.astro | 4 +-- src/pages/docs/research.astro | 5 +--- src/pages/docs/security.astro | 2 +- src/pages/docs/tags.astro | 2 +- src/pages/for/compatibility.astro | 11 ++++---- src/pages/for/mcp.astro | 4 +-- src/pages/for/networks.astro | 4 +-- src/pages/for/p2p.astro | 13 +++++---- src/pages/for/setups.astro | 8 +++--- src/pages/for/setups/[slug].astro | 2 +- src/pages/for/skills.astro | 2 +- src/pages/index.astro | 28 +++++++++---------- src/pages/plans.astro | 6 ++-- src/pages/press.astro | 3 -- src/pages/privacy.astro | 4 +-- src/pages/publish.astro | 4 +-- src/pages/terms.astro | 2 +- 74 files changed, 196 insertions(+), 195 deletions(-) diff --git a/src/components/Nav.astro b/src/components/Nav.astro index 9bfac85..7e1b497 100644 --- a/src/components/Nav.astro +++ b/src/components/Nav.astro @@ -1,13 +1,12 @@ --- interface Props { - active?: 'home' | 'docs' | 'blog' | 'plans' | 'for'; + active?: 'home' | 'docs' | 'blog' | 'plans' | 'for' | 'tech' | 'apps'; } const { active } = Astro.props; const forLinks = [ { href: '/for/p2p', label: 'Direct P2P', desc: 'Peer-to-peer for AI agents' }, { href: '/for/mcp', label: 'MCP + Pilot', desc: 'Give your MCP servers a network' }, - { href: '/app-store', label: 'App Store', desc: 'Agent apps, one command to install' }, { href: '/for/networks', label: 'Networks', desc: 'Domain networks agents self-organize into' }, ]; @@ -48,8 +47,10 @@ const statusText = version ? `Network live · v${version}` : 'Network live'; data-track="nav_click" data-track-target="docs">Docs Blog + App Store Plans + data-track="nav_click" data-track-target="plans">Plans
- -

To check a bundle without installing it, pilotctl appstore verify <bundle-dir> sha256-checks every file in a pre-install bundle against its manifest and reports any mismatch — a tampered or wrongly-built bundle fails here before it ever reaches the install root.

+

To check a bundle without installing it, pilotctl appstore verify <bundle-dir> validates the manifest and sha256-checks the manifest-pinned binary against it, reporting any mismatch — a tampered or wrongly-built bundle fails here before it ever reaches the install root.

Security model & hardening

-

The app store is deny-by-default at every layer. Trust flows from a signed catalogue, through a signed manifest, to a sandboxed and continuously-verified child process.

+

The app store is deny-by-default at every layer. Trust flows from a signed catalogue, through a signed manifest, to a manifest-gated, resource-limited child process (rlimits + a syscall/IPC broker; OS-level sandboxing such as landlock/seccomp is not yet wired).

Signed catalogue (fail-closed)

@@ -204,7 +204,7 @@ ipc.Serve(ctx, conn, d) // on the --socket the daemon su

Worked example: io.pilot.cosift

-

The cosift app is a stateless adapter to a search / answer / research API over a multi-million-document web corpus. It exposes three utility methods and several status/discovery ones:

+

The cosift app is a stateless adapter to a search / answer / research API over a multi-million-document web corpus. It exposes several utility methods (search, answer, research, and more) plus status/discovery ones:

# Discover the surface + latencies
 pilotctl appstore call io.pilot.cosift cosift.help '{}'
@@ -218,7 +218,7 @@ ipc.Serve(ctx, conn, d)   // on the --socket the daemon su
 # research (slow) - plan -> multi-retrieval -> report
 pilotctl appstore call io.pilot.cosift cosift.research '{"q":"compare raft and paxos"}'
-

Its source is a public reference for app authors: a tiny adapter, a manifest, and the publish flow above.

+

The cosift backend is open source (pilot-protocol/cosift); the app follows the same tiny-adapter + signed-manifest + publish flow shown above.

`; --- From d01cbae36558d4012af7971b511ca7c1f0b137a8 Mon Sep 17 00:00:00 2001 From: Teodor Calin Date: Fri, 10 Jul 2026 22:06:44 +0300 Subject: [PATCH 15/75] audit-fix: for/compatibility (16 false, 33 unverifiable resolved) Fixed broken install commands: --email is rejected by install.sh (exit 2); every example now uses PILOT_EMAIL= env (+ PILOT_ALLOW_ROOT=1 for root containers). Corrected SDK claims (Unix-socket clients of a local daemon, no HTTPS/WSS/browser path), plist name + non-auto-load, systemd not-enabled, and HTTPS_PROXY 'tracked on GitHub' (no such issue; not supported). Reframed 30 unverifiable per-vendor cells as best-effort notes; dropped unbenchmarked latency figures. Co-Authored-By: Claude Fable 5 --- audit/PROGRESS.md | 2 +- audit/for/compatibility.md | 5 ++++ src/pages/for/compatibility.astro | 40 +++++++++++++++---------------- 3 files changed, 26 insertions(+), 21 deletions(-) diff --git a/audit/PROGRESS.md b/audit/PROGRESS.md index 73ccf7c..5e078a9 100644 --- a/audit/PROGRESS.md +++ b/audit/PROGRESS.md @@ -19,7 +19,7 @@ Started 2026-07-10. Status: todo | in-progress | done | blocked. | ledger | false | unverifiable | status | |---|---:|---:|---| | audit/docs/consent.md | 33 | 6 | done | -| audit/for/compatibility.md | 16 | 33 | todo | +| audit/for/compatibility.md | 16 | 33 | done | | audit/docs/enterprise-blueprints.md | 24 | 0 | todo | | audit/pages/privacy.md | 11 | 37 | todo | | audit/docs/cli-reference.md | 21 | 6 | done | diff --git a/audit/for/compatibility.md b/audit/for/compatibility.md index f1899f2..3d7fa14 100644 --- a/audit/for/compatibility.md +++ b/audit/for/compatibility.md @@ -67,3 +67,8 @@ Audited: 2026-07-10 · Sentences examined: 140 · verified: 69 · false: 16 · u - Local site tree (src/pages/docs/): firewalls.astro, getting-started.astro exist — verifies /docs/firewalls and /docs/getting-started links (4 occurrences). - Live URLs: https://pilotprotocol.network/install.sh (200), https://vulturelabs.com (200, JSON-LD publisher), https://github.com/pilot-protocol/pilotprotocol/releases/latest (302 to latest). - Definitional/logical: Coolify/CapRover self-hosted inherits host firewall; VM cards (security-group control, bare metal); Coder inherits provider; tmux/screen no auto-restart; k8s sidecar over /shared/pilot.sock; "Works under any NetworkPolicy that permits egress to TCP/443"; browser/WASM "daemon needs POSIX". + +## Resolutions (2026-07-10, loop iteration 8) +All 16 FALSE resolved + 33 UNVERIFIABLE addressed. Re-verified against live install.sh + source: the parser (install.sh:91-118) accepts only --version/--channel/--yes/--no-warn/--help/-- and rejects `--email` with exit 2 (email = PILOT_EMAIL env or prompt); root containers need PILOT_ALLOW_ROOT=1; plist is network.pilotprotocol.pilot-daemon.plist and is NOT auto-loaded (installer prints launchctl load); systemd units written but not enabled; SDKs (sdk-node/sdk-python) are Unix-socket clients of a local daemon (no HTTPS/WSS/browser path); WSS dial does not honor HTTPS_PROXY (wss.go Transport.Proxy nil) and no GitHub issue tracks it. +- FALSE fixes: every `--email` example → `PILOT_EMAIL=... [PILOT_ALLOW_ROOT=1] sh`; Lambda/browser SDK claims corrected (SDK needs local daemon); proxy row + legend + Replit note reworded to "not yet supported" (no tracking issue); plist name/load + systemd enable corrected. +- UNVERIFIABLE (30 vendor-behavior cells + latency + verification-date): can't test 30 platforms in-loop → reframed the matrix disclaimer as best-effort, uncertified platform notes (removed fabricated "last verified June 2026"); latency figures (~10-30ms/~50-200ms/~1.5-2×) replaced with relative "RTT-bound / +1 hop via beacon" framing (no benchmark to cite). diff --git a/src/pages/for/compatibility.astro b/src/pages/for/compatibility.astro index 44d8842..cbb6d8e 100644 --- a/src/pages/for/compatibility.astro +++ b/src/pages/for/compatibility.astro @@ -40,7 +40,7 @@ const groups: CategoryGroup[] = [ category: 'Serverless / functions', blurb: "Three out of four can't host a persistent process. Cloud Run is the exception when min-instances=1.", cards: [ - { name: 'AWS Lambda', mode: 'wrong runtime', modeClass: 'wrong', note: '15-min hard timeout kills the tunnel. Use the SDK in the handler, not the daemon.' }, + { name: 'AWS Lambda', mode: 'wrong runtime', modeClass: 'wrong', note: '15-min hard timeout kills the tunnel; no persistent daemon. Run the daemon as a Lambda Extension only while warm.' }, { name: 'Google Cloud Run', mode: 'compat', modeClass: 'compat', note: 'Set min-instances=1 to keep warm. Inbound is HTTPS-only.' }, { name: 'Vercel / Netlify / GCP Functions', mode: 'wrong runtime', modeClass: 'wrong', note: 'Ephemeral execution — no persistent process model.' }, { name: 'Cloudflare Workers', mode: 'wrong runtime', modeClass: 'wrong', note: 'No long-lived sockets, no UDP, no listen().' }, @@ -69,7 +69,7 @@ const groups: CategoryGroup[] = [ blurb: 'A mix. Modal/E2B/Daytona/Codespaces are open; Docker-AI-Sandbox-class (Replit Agent, Devin) blocks raw TCP.', cards: [ { name: 'Cursor Cloud Agents', mode: 'allowlist', modeClass: 'compat', note: 'Add *.pilotprotocol.network + 34.71.57.205 to the egress allowlist.' }, - { name: 'Replit Agent', mode: 'compat+proxy', modeClass: 'proxy', note: 'Docker AI Sandbox — raw TCP/UDP blocked. HTTPS_PROXY support tracked on GitHub.' }, + { name: 'Replit Agent', mode: 'compat+proxy', modeClass: 'proxy', note: 'Docker AI Sandbox — raw TCP/UDP blocked. HTTPS_PROXY is not supported yet.' }, { name: 'Devin (Cognition)', mode: 'compat+proxy', modeClass: 'proxy', note: 'Same Docker AI Sandbox model.' }, { name: 'Modal Sandboxes', mode: 'udp', modeClass: 'udp', note: 'Default-allow. Long timeout for persistent run.' }, { name: 'E2B Sandboxes', mode: 'udp', modeClass: 'udp', note: 'IP/CIDR rules only; Pilot endpoints allowed by default.' }, @@ -85,17 +85,17 @@ const groups: CategoryGroup[] = [ category: 'Desktop / local', blurb: 'install.sh wires up the right supervisor for each OS.', cards: [ - { name: 'macOS (LaunchAgent)', mode: 'udp', modeClass: 'udp', note: '~/Library/LaunchAgents/network.pilotprotocol.daemon.plist auto-loaded.' }, - { name: 'Linux (systemd)', mode: 'udp', modeClass: 'udp', note: 'sudo install enables the system unit + auto-updater.' }, + { name: 'macOS (LaunchAgent)', mode: 'udp', modeClass: 'udp', note: '~/Library/LaunchAgents/network.pilotprotocol.pilot-daemon.plist written; load it with launchctl.' }, + { name: 'Linux (systemd)', mode: 'udp', modeClass: 'udp', note: 'sudo install writes the pilot-daemon + updater units; enable/start them with systemctl.' }, { name: 'tmux / screen', mode: 'udp', modeClass: 'udp', note: 'Ad-hoc dev only — no auto-restart.' }, { name: 'Windows', mode: 'not shipped', modeClass: 'wrong', note: 'No Windows binary yet — use WSL2 (Linux mode).' }, ], }, { category: 'Browser / WASM', - blurb: 'Use the JS/Python SDK from your app; the daemon needs a POSIX runtime.', + blurb: 'The daemon needs a POSIX runtime; the SDKs need a local daemon over a Unix socket, so neither runs in a browser tab or WASM.', cards: [ - { name: 'Browser tab', mode: 'wrong runtime', modeClass: 'wrong', note: 'No raw sockets — use the JS SDK over WSS instead.' }, + { name: 'Browser tab', mode: 'wrong runtime', modeClass: 'wrong', note: 'No raw sockets, and the JS SDK is Node-only (Unix-socket client of a local daemon) — neither works here.' }, { name: 'WASM runtime', mode: 'wrong runtime', modeClass: 'wrong', note: 'Same model — daemon needs POSIX.' }, ], }, @@ -104,9 +104,9 @@ const groups: CategoryGroup[] = [ const egress = [ { model: 'Open egress', examples: 'home wifi, most cloud VMs, default Docker', today: '✓ UDP works — use default', needed: 'nothing' }, { model: 'Default-deny, TCP/443 only', examples: 'hotel / airport / locked corp wifi', today: '✓ Compat works as-is — single TCP/443 outbound', needed: '-transport=compat' }, - { model: 'HTTP CONNECT proxy', examples: 'corp networks with explicit proxy URL', today: '~ WSS dial honors HTTPS_PROXY; registry TLS dial does not', needed: 'tracked on GitHub — registry over HTTPS_PROXY' }, + { model: 'HTTP CONNECT proxy', examples: 'corp networks with explicit proxy URL', today: '✗ Neither the WSS dial nor the registry TLS dial honors HTTPS_PROXY today', needed: 'not yet supported' }, { model: 'Transparent TLS interception', examples: 'Zscaler, Fortinet, Palo Alto, BlueCoat, Netskope', today: '✓ Works with -tls-trust=system (corp CA in OS store — current default)', needed: 'already supported' }, - { model: 'HTTP-proxy-only sandbox', examples: 'Replit Agent, Devin, Docker AI Sandbox', today: '✗ Blocked — daemon needs raw TCP to :443', needed: 'tracked on GitHub — HTTPS_PROXY via CONNECT' }, + { model: 'HTTP-proxy-only sandbox', examples: 'Replit Agent, Devin, Docker AI Sandbox', today: '✗ Blocked — daemon needs raw TCP to :443', needed: 'not yet supported' }, { model: 'Domain-name allowlist', examples: 'Cursor Cloud Agents, Zscaler PAC', today: '✓ Works after adding *.pilotprotocol.network + 34.71.57.205', needed: 'doc-only' }, { model: 'DPI / protocol allowlist', examples: 'Great Firewall, Iran-style filters', today: '✗ Blocked — no domain fronting / ECH today', needed: 'out of scope' }, ]; @@ -324,7 +324,7 @@ const egress = [ The daemon binds a public UDP socket; peers reach you directly or via beacon hole-punch. Lowest latency. Needs outbound UDP/4000 (and inbound on it for a public node).
-
~10–30 ms
one-way
+
RTT-bound
direct path
UDP/4000
required
Getting started →
@@ -337,11 +337,11 @@ const egress = [
Compat mode
- Long-lived TCP/443 connections only — WebSocket Secure to the beacon for the data plane, TLS to the registry for control. Zero UDP. Same overlay; same Ed25519 trust; ~1.5–2× latency. + Long-lived TCP/443 connections only — WebSocket Secure to the beacon for the data plane, TLS to the registry for control. Zero UDP. Same overlay; same Ed25519 trust; higher latency than a direct path (traffic relays through the beacon).
TCP/443
single port
-
~50–200 ms
one-way
+
+1 hop
via beacon
Firewall docs →
@@ -358,10 +358,10 @@ const egress = [
udp — default UDP transport compat-transport=compat - compat+proxy — needs HTTPS_PROXY (tracked on GitHub) + compat+proxy — would need HTTPS_PROXY support (not yet available) wrong runtime — no daemon
-

Vendor behavior last verified June 2026. Platforms change their network policies — if a cell is out of date, tell us.

+

These per-platform notes are our best-effort understanding of each vendor's network policy, not continuously tested guarantees — vendors change their rules, so verify against your platform's current docs and tell us if a cell is wrong.

{groups.map((g) => (
@@ -445,7 +445,7 @@ FROM debian:bookworm-slim RUN apt-get update && apt-get install -y curl ca-certificates \ && rm -rf /var/lib/apt/lists/* RUN curl -fsSL https://pilotprotocol.network/install.sh | \ - sh -s -- --email you@example.com + PILOT_EMAIL=you@example.com PILOT_ALLOW_ROOT=1 sh ENTRYPOINT ["/root/.pilot/bin/pilot-daemon", "-transport=compat"]

No port exposed. Render allows arbitrary outbound TCP/443. Zero UDP, zero TCP/9000.

@@ -453,7 +453,7 @@ ENTRYPOINT ["/root/.pilot/bin/pilot-daemon", "-transport=compat"]

AWS Lambda — don't

-

Lambda has a 15-minute hard timeout and freezes the execution environment between invocations. A Lambda Extension can host a sidecar process but only while the function is warm. Wrong runtime for pilot-daemon. If you want Pilot-from-Lambda, call the registry directly via the JS or Python SDK over HTTPS during the handler invocation; don't try to run the daemon.

+

Lambda has a 15-minute hard timeout and freezes the execution environment between invocations. A Lambda Extension can host a sidecar process but only while the function is warm. Wrong runtime for pilot-daemon. The JS and Python SDKs are not a way around this — both are clients of a local pilot-daemon over a Unix socket, so they still need the daemon running. A Lambda Extension can host the daemon while the function is warm; there is no daemon-less SDK path.

@@ -471,7 +471,7 @@ spec: command: ["/bin/sh", "-c"] args: - curl -fsSL https://pilotprotocol.network/install.sh | \ - sh -s -- --email pilot@example.com && + PILOT_EMAIL=pilot@example.com PILOT_ALLOW_ROOT=1 sh && exec /root/.pilot/bin/pilot-daemon -transport=compat \ -socket /shared/pilot.sock volumeMounts: [{`{ name: pilot-sock, mountPath: /shared }`}] @@ -484,16 +484,16 @@ spec:

macOS laptop — LaunchAgent

curl -fsSL https://pilotprotocol.network/install.sh | \
-  sh -s -- --email you@example.com
+ PILOT_EMAIL=you@example.com sh
-

Installer writes ~/Library/LaunchAgents/network.pilotprotocol.daemon.plist and loads it. Defaults to -transport=udp; flip to compat only if your network blocks UDP/4000.

+

Installer writes ~/Library/LaunchAgents/network.pilotprotocol.pilot-daemon.plist and prints the launchctl load command to start it. Defaults to -transport=udp; flip to compat only if your network blocks UDP/4000.

Forced-compat systemd unit — locked-down corp Linux

-
sudo curl -fsSL https://pilotprotocol.network/install.sh | \
-  sudo PILOT_ALLOW_ROOT=1 sh -s -- --email you@example.com
+
curl -fsSL https://pilotprotocol.network/install.sh | \
+  sudo PILOT_EMAIL=you@example.com PILOT_ALLOW_ROOT=1 sh
 sudo systemctl edit pilot-daemon   # add ExecStart override with -transport=compat
 sudo systemctl restart pilot-daemon
From d0af14058281812f535d0bcd95bf366bf2bb7ee2 Mon Sep 17 00:00:00 2001 From: Teodor Calin Date: Fri, 10 Jul 2026 22:11:11 +0300 Subject: [PATCH 16/75] audit-fix: docs/enterprise-blueprints (24 false resolved) Rewrote the blueprint format + provision RPC docs to match the actual wire format (common@v0.5.7): join_rule open|token|invite, webhooks object {audit_url,identity_url}, roles []{external_id,role} incl owner, RPC key 'type' not 'command', get_provision_status takes no network_id, correct common/registry import paths (no ToMap helper), real action strings, correct step order, roles are pre-assignments. Logged install.sh --email fix to needs-user. Co-Authored-By: Claude Fable 5 --- audit/PROGRESS.md | 4 +- audit/docs/enterprise-blueprints.md | 3 + src/pages/docs/enterprise-blueprints.astro | 75 +++++++++++----------- 3 files changed, 42 insertions(+), 40 deletions(-) diff --git a/audit/PROGRESS.md b/audit/PROGRESS.md index 5e078a9..1f28008 100644 --- a/audit/PROGRESS.md +++ b/audit/PROGRESS.md @@ -13,6 +13,8 @@ Started 2026-07-10. Status: todo | in-progress | done | blocked. | GA4 loads unconditionally on /plain (GDPR) | FIXED — removed GA4 from PlainLayout entirely (plain = JS-stripped agent surface) | website #116 | n/a | ## Needs user review +- **install.sh `--email` flag** (product-fix candidate): the compatibility examples used `--email`, which install.sh rejects (exit 2); website now uses `PILOT_EMAIL=` env. install.sh's OWN header comment still references `--email`. Options: add a real `--email` flag to the installer parser (makes the natural UX work, matches the header) OR fix the header comment. Touches release/install.sh → needs R2 deploy via pilot-release worker, so parking for your greenlight. + - (none yet) ## Pages @@ -20,7 +22,7 @@ Started 2026-07-10. Status: todo | in-progress | done | blocked. |---|---:|---:|---| | audit/docs/consent.md | 33 | 6 | done | | audit/for/compatibility.md | 16 | 33 | done | -| audit/docs/enterprise-blueprints.md | 24 | 0 | todo | +| audit/docs/enterprise-blueprints.md | 24 | 0 | done | | audit/pages/privacy.md | 11 | 37 | todo | | audit/docs/cli-reference.md | 21 | 6 | done | | audit/docs/enterprise-identity.md | 22 | 0 | todo | diff --git a/audit/docs/enterprise-blueprints.md b/audit/docs/enterprise-blueprints.md index d60ab8b..b6e7807 100644 --- a/audit/docs/enterprise-blueprints.md +++ b/audit/docs/enterprise-blueprints.md @@ -43,3 +43,6 @@ Sources of truth: `wire` = /Users/calinteodor/go/pkg/mod/github.com/pilot-protoc - Opinion (3): "designed for infrastructure-as-code workflows"; "Store them in version control, review changes in pull requests..."; "Use this to verify... or to diff the current state against a desired state." - Example (4): placeholder values in code blocks — `prod-fleet`, example.com URLs, `hec-token-here`, `your-admin-token`, `network_id: 5`. Not flagged (illustrative), except where the surrounding shape is itself false (flagged above). + +## Resolutions (2026-07-10, loop iteration 9) +All 24 FALSE resolved against common@v0.5.7/registry/wire/blueprint.go + rendezvous provision.go (re-verified): join_rule enum open|token|invite (not invite_only); webhooks is object {audit_url,identity_url} not array-with-events; roles is []{external_id,role} with owner|admin|member (not node-ID map, owner IS valid); RPC key is "type" not "command"; get_provision_status takes no network_id (registry-wide summary); import path common/registry/{wire,client} not pilotprotocol/pkg/registry; no ToMap helper; action strings corrected to actual fmt.Sprintf outputs; response "provision_network_ok"; step order webhooks(5) then audit(6); roles are pre-assignments applied on later join (membership not required); blueprint path assigns no owner and does not range-check policy fields; failures return an error, not itemized in result. diff --git a/src/pages/docs/enterprise-blueprints.astro b/src/pages/docs/enterprise-blueprints.astro index 25c99d8..7e4c1d8 100644 --- a/src/pages/docs/enterprise-blueprints.astro +++ b/src/pages/docs/enterprise-blueprints.astro @@ -28,7 +28,7 @@ const bodyContent = `

Blueprints

{
   "name": "prod-fleet",
-  "join_rule": "invite_only",
+  "join_rule": "invite",
   "enterprise": true,
   "policy": {
     "max_members": 100,
@@ -40,21 +40,19 @@ const bodyContent = `

Blueprints

"url": "https://accounts.example.com/.well-known/openid-configuration", "client_id": "pilot-prod" }, - "webhooks": [ - { - "url": "https://ops.example.com/pilot-events", - "events": ["member.kicked", "network.policy_changed"] - } - ], + "webhooks": { + "audit_url": "https://ops.example.com/pilot-audit", + "identity_url": "https://ops.example.com/pilot-identity" + }, "audit_export": { "format": "splunk_hec", "endpoint": "https://splunk.example.com:8088/services/collector", "token": "hec-token-here" }, - "roles": { - "42": "admin", - "108": "admin" - }, + "roles": [ + {"external_id": "alice@example.com", "role": "admin"}, + {"external_id": "bob@example.com", "role": "member"} + ], "network_admin_token": "network-specific-secret" }
@@ -64,13 +62,13 @@ const bodyContent = `

Blueprints

FieldTypeRequiredDescription namestringYesNetwork name. Lowercase alphanumeric with hyphens. Used for idempotent lookup. - join_rulestringNoOne of open, invite_only, or token. Defaults to open. + join_rulestringNoOne of open, token, or invite. Defaults to open. enterpriseboolNoEnable enterprise features. Defaults to false. policyobjectNoNetwork policy: max_members, allowed_ports, description. See Network Policies. identity_providerobjectNoIDP configuration: type, url, client_id. See Identity & SSO. - webhooksarrayNoWebhook endpoints: url and events filter. + webhooksobjectNoWebhook endpoints: audit_url and identity_url. audit_exportobjectNoExport config: format, endpoint, token. See Audit Export. - rolesobjectNoMap of node ID (string) → role (admin or member). Pre-assigns RBAC roles. + rolesarrayNoRBAC pre-assignments by external identity: [{external_id, role}] where role is owner, admin, or member. Applied when a matching node joins. network_admin_tokenstringNoPer-network admin token for delegated administration. @@ -84,12 +82,12 @@ const bodyContent = `

Blueprints

  • Enable enterprise - if enterprise: true and the network is not yet enterprise, enable it.
  • Set policies - apply the policy object using merge-on-update semantics.
  • Configure IDP - set the identity provider configuration if specified.
  • +
  • Configure webhooks - register the audit_url / identity_url endpoints if specified.
  • Configure audit export - set the audit export endpoint and format if specified.
  • -
  • Configure webhooks - register webhook endpoints if specified.
  • -
  • Assign roles - for each entry in roles, set the RBAC role. Nodes must already be members of the network.
  • +
  • Pre-assign roles - store each {external_id, role} as a pre-assignment; the role is applied when a node with that external identity later joins. Membership is not required at apply time.
  • -

    Each step is independent - if a later step fails, earlier steps are not rolled back. The result includes which actions were taken and which failed.

    +

    Each step is independent - if a later step fails, earlier steps are not rolled back, and the call returns an error immediately. The result's actions list names only the steps that succeeded; failures are surfaced as the returned error, not itemized in the result.

    Idempotency

    @@ -108,22 +106,19 @@ const bodyContent = `

    Blueprints

    • name is required and must match the network name rules (lowercase alphanumeric with hyphens)
    • -
    • join_rule must be one of open, invite_only, or token
    • -
    • policy.max_members must be a non-negative integer
    • -
    • policy.allowed_ports must have ≤ 100 entries
    • -
    • policy.description must be ≤ 256 characters
    • +
    • join_rule must be one of open, token, or invite
    • identity_provider.type must be a valid provider type (oidc, saml, entra_id, ldap, webhook)
    • -
    • roles values must be admin or member (not owner - ownership is assigned to the creator)
    • +
    • roles values must be owner, admin, or member
    -

    If validation fails, no changes are made and the error is returned immediately.

    +

    If validation fails, no changes are made and the error is returned immediately. (Policy fields like max_members and allowed_ports are not range-checked on the blueprint path — those limits apply to the separate set_network_policy RPC.)

    Protocol command

    Apply a blueprint

    {
    -  "command": "provision_network",
    +  "type": "provision_network",
       "blueprint": {
         "name": "prod-fleet",
         "enterprise": true,
    @@ -132,7 +127,7 @@ const bodyContent = `

    Blueprints

    "admin_token": "your-admin-token" }
    -

    The blueprint is the only payload field besides admin_token. Ownership of a newly-created network is assigned to the registry node that the admin token authorizes — there is no explicit node_id on the RPC.

    +

    The blueprint is the only payload field besides admin_token. The admin token is a global registry token; no network owner is assigned by the blueprint path, and there is no explicit node_id on the RPC.

    Result format

    @@ -140,11 +135,12 @@ const bodyContent = `

    Blueprints

    "network_id": 5, "name": "prod-fleet", "created": true, + "type": "provision_network_ok", "actions": [ - "network created", - "enterprise enabled", - "policy set", - "audit export configured" + "created network 5 (prod-fleet)", + "enabled enterprise features", + "applied network policy", + "configured splunk_hec audit export to https://splunk.example.com:8088/..." ] } @@ -152,28 +148,29 @@ const bodyContent = `

    Blueprints

    File-based blueprints

    -

    For programmatic use, load a blueprint from a JSON file using the helper in pkg/registry/wire, then convert to the map shape ProvisionNetwork expects:

    +

    For programmatic use, load a blueprint from a JSON file with the typed loader in the common/registry/wire package, then pass it to the client:

    -
    // Go SDK — pkg/registry/wire has the typed loader
    -import "github.com/pilot-protocol/pilotprotocol/pkg/registry/wire"
    -import "github.com/pilot-protocol/pilotprotocol/pkg/registry"
    +  
    // Go SDK — the typed loader lives in common/registry/wire
    +import "github.com/pilot-protocol/common/registry/wire"
    +import "github.com/pilot-protocol/common/registry/client"
     
    -bp, err := wire.LoadBlueprint("network.json")        // *wire.NetworkBlueprint
    -result, err := client.ProvisionNetwork(bp.ToMap(), adminToken)
    +bp, err := wire.LoadBlueprint("network.json") // *wire.NetworkBlueprint +// ProvisionNetwork takes a map[string]interface{} blueprint + admin token. +// Marshal the blueprint JSON into a map, or build the map directly. +result, err := c.ProvisionNetwork(blueprintMap, adminToken)
    -

    wire.LoadBlueprint reads and validates the JSON file, returning a typed struct. registry.Client.ProvisionNetwork(blueprint, adminToken) takes the blueprint as a map[string]interface{} and the admin token — the network owner is the node already authenticated on the client connection (no explicit nodeID argument).

    +

    wire.LoadBlueprint reads and validates the JSON file, returning a typed struct. client.Client.ProvisionNetwork(blueprint, adminToken) takes the blueprint as a map[string]interface{} and the admin token. There is no explicit nodeID argument, and the blueprint path assigns no network owner.

    Status query

    Inspect the provisioning state of a network:

    {
    -  "command": "get_provision_status",
    -  "network_id": 5,
    +  "type": "get_provision_status",
       "admin_token": "your-admin-token"
     }
    -

    Returns the network’s current configuration as seen by the registry: enterprise status, policies, IDP config, webhook endpoints, audit export, and role assignments. Use this to verify that a blueprint was applied correctly or to diff the current state against a desired state.

    +

    Takes no network_id — it returns a registry-wide summary of all networks. Per network you get enterprise status, policy, idp_type, an audit format string, a webhook_enabled flag, and an rbac_pre_assignments count (a summary, not full configs or endpoints). Use it to verify a blueprint was applied.

    See also: Enterprise Overview - the full enterprise feature set. Network Policies - policy fields that blueprints configure. Audit Export - export formats and delivery guarantees. From 4f670ecee92c6d7aae5190456d46b24d3ce12662 Mon Sep 17 00:00:00 2001 From: Teodor Calin Date: Fri, 10 Jul 2026 22:15:38 +0300 Subject: [PATCH 17/75] audit-fix: cookies (7 false, 4 unverifiable resolved) GA4-on-/plain rows resolved by the earlier PlainLayout fix (no GA4 there now, so 'set only after consent' is true). Completed the storage inventory (added pilot-theme + two publish-page localStorage keys), corrected the 'Cookie Preferences on every page' claim (marketing footer only), softened __cf_bm (not observed live) and Cloudflare Web Analytics wording, accepted the policy effective dates. Co-Authored-By: Claude Fable 5 --- audit/PROGRESS.md | 2 +- audit/pages/cookies.md | 4 ++++ src/pages/cookies.astro | 31 ++++++++++++++++++++++++++----- 3 files changed, 31 insertions(+), 6 deletions(-) diff --git a/audit/PROGRESS.md b/audit/PROGRESS.md index 1f28008..63a49c6 100644 --- a/audit/PROGRESS.md +++ b/audit/PROGRESS.md @@ -61,7 +61,7 @@ Started 2026-07-10. Status: todo | in-progress | done | blocked. | audit/blog/openclaw-agents-behind-nat-zero-config.md | 4 | 14 | todo | | audit/blog/replace-message-broker-twelve-lines-go.md | 6 | 8 | todo | | audit/blog/run-agent-network-without-cloud-dependency.md | 4 | 13 | todo | -| audit/pages/cookies.md | 7 | 4 | todo | +| audit/pages/cookies.md | 7 | 4 | done | | audit/pages/publish.md | 3 | 16 | todo | | audit/blog/move-beyond-rest-persistent-connections-for-agents.md | 5 | 9 | todo | | audit/blog/trust-model-agents-invisible-by-default.md | 6 | 6 | todo | diff --git a/audit/pages/cookies.md b/audit/pages/cookies.md index 5c65ff6..ea3999a 100644 --- a/audit/pages/cookies.md +++ b/audit/pages/cookies.md @@ -38,3 +38,7 @@ Audited: 2026-07-10 · Sentences examined: 52 · verified: 35 · false: 7 · unv - L101 both sentences ("We will post changes…", "…we will re-prompt for consent where required by law.") — future commitments. - L104 "Questions about cookies or our use of analytics?" — rhetorical. - L108 "This policy was drafted for transparency…" — self-characterization. + +## Resolutions (2026-07-10, loop iteration 10) +FALSE: GA4-on-/plain rows (64/71/85/87) resolved by product fix (GA4 removed from PlainLayout — verified grep gtag=0), so "_ga set only after consent" is now true. Inventory completed: added pilot-theme, pilot.publish.draft.v1, pilot.publish.ui.v1 localStorage rows (grep confirms these + pilot_consent are the only storage keys site-wide), so "every cookie/browser-storage entry" (line 34) + meta description are now accurate. "Cookie Preferences at bottom of every page" → corrected to "in the footer on marketing pages" (DocsFooter/PlainLayout have no such link) + pointed to clearing pilot_consent. +UNVERIFIABLE: __cf_bm not observed in live Set-Cookie (curl 2026-07-10) → softened to "may be set when bot protection is active"; CF Web Analytics "no personal data collected" → reworded to cookieless/no-fingerprint + honest IP/UA-to-Cloudflare note; policy effective dates (May 28 2026) → ACCEPTED (operator's legal declaration, not code-verifiable). diff --git a/src/pages/cookies.astro b/src/pages/cookies.astro index 57a90bc..71ba49a 100644 --- a/src/pages/cookies.astro +++ b/src/pages/cookies.astro @@ -5,7 +5,7 @@ import Footer from '../components/Footer.astro'; import '../styles/system.css'; const title = "Cookie Policy — Pilot Protocol"; -const description = "How Pilot Protocol uses cookies and similar technologies. Transparent inventory of all cookies, localStorage entries, and analytics tools."; +const description = "How Pilot Protocol uses cookies and similar technologies. Transparent inventory of the cookies, localStorage entries, and analytics tools we use."; const canonicalUrl = "https://pilotprotocol.network/cookies"; --- @@ -47,7 +47,7 @@ const canonicalUrl = "https://pilotprotocol.network/cookies"; __cf_bm Cloudflare - Bot management. Distinguishes human visitors from automated bots to protect the site from malicious traffic. Does not track users across sites. + Bot management. Cloudflare may set this to distinguish human visitors from automated bots when bot protection is active on the zone. Does not track users across sites. 30 minutes Strictly necessary @@ -58,6 +58,27 @@ const canonicalUrl = "https://pilotprotocol.network/cookies"; Persistent (until cleared) Strictly necessary + + pilot-theme + Pilot Protocol (localStorage) + Remembers your light/dark theme choice. No personal data, no tracking. + Persistent (until cleared) + Functional + + + pilot.publish.draft.v1 + Pilot Protocol (localStorage) + Saves your in-progress app-submission draft on the Publish page so you don't lose it on reload. Set only if you use that form. + Persistent (until cleared) + Functional + + + pilot.publish.ui.v1 + Pilot Protocol (localStorage) + Remembers UI state on the Publish page (e.g. which step you're on). Set only if you use that form. + Persistent (until cleared) + Functional + _ga Google Analytics @@ -76,20 +97,20 @@ const canonicalUrl = "https://pilotprotocol.network/cookies";

    Cookieless Analytics

    -

    In addition to the cookies above, we use Cloudflare Web Analytics, which is entirely cookieless. It does not use cookies, localStorage, fingerprinting, or any form of persistent tracking. It provides only aggregated page-view counts and performance metrics. No personal data is collected.

    +

    In addition to the cookies above, we use Cloudflare Web Analytics, which is entirely cookieless. It sets no cookies or localStorage and does no client-side fingerprinting or persistent tracking; it reports only aggregated page-view and performance metrics. (As with any web request, the analytics beacon transmits your IP and user-agent to Cloudflare; see Cloudflare's privacy documentation for how they handle it.)

    Consent Model

    When you first visit pilotprotocol.network, a consent banner appears offering two options:

    • Accept — Enables Google Analytics 4 cookies (_ga, _ga_EEWEKT0GW5). Your preference is stored in the pilot_consent localStorage entry.
    • -
    • Reject — No analytics cookies are set. The strictly necessary __cf_bm cookie (Cloudflare bot management) still operates. Your preference is stored in pilot_consent.
    • +
    • Reject — No analytics cookies are set. If Cloudflare bot management is active, its strictly-necessary __cf_bm cookie may still be set. Your preference is stored in pilot_consent.

    The banner does not use a "nag wall" — you can browse the site without interacting with it. If you do not make a choice, no analytics cookies are set (implied rejection).

    How to Change Your Preference

    You can change your consent at any time:

      -
    1. Cookie preferences link — At the bottom of every page in the footer, click "Cookie Preferences" to reopen the consent banner.
    2. +
    3. Cookie preferences link — In the site footer (on the main marketing pages), click "Cookie Preferences" to reopen the consent banner. You can also clear the pilot_consent entry (below) to make the banner reappear.
    4. Clear localStorage — Removing pilot_consent from your browser's localStorage will reset your preference, and the banner will reappear on your next visit.
    5. Browser settings — Most browsers allow you to block or delete cookies globally. See your browser's help documentation for instructions.
    From 04aefbd5f07a37c541631119cdf412e87733fc74 Mon Sep 17 00:00:00 2001 From: Teodor Calin Date: Fri, 10 Jul 2026 22:19:47 +0300 Subject: [PATCH 18/75] audit-fix: privacy (11 false, 37 unverifiable resolved) Corrected factual claims vs source: synthetic email derivation (pubkey first 6 bytes, not SHA-256), LAN IP (collected on UDP + sent to registry, not opt-in), 'never touches infrastructure' qualified to direct mode, review-prompt default-off, GA4 retention, TLS 1.3 -> TLS 1.2+ (MinVersion), clear-email -> set-email, last-updated bumped. Cloudflare Web Analytics verified live-deployed. Legal declarations accepted; SMS-section (no implementation) flagged to needs-user. Co-Authored-By: Claude Fable 5 --- audit/PROGRESS.md | 4 +++- audit/pages/privacy.md | 4 ++++ src/pages/privacy.astro | 18 +++++++++--------- 3 files changed, 16 insertions(+), 10 deletions(-) diff --git a/audit/PROGRESS.md b/audit/PROGRESS.md index 63a49c6..3417da4 100644 --- a/audit/PROGRESS.md +++ b/audit/PROGRESS.md @@ -17,13 +17,15 @@ Started 2026-07-10. Status: todo | in-progress | done | blocked. - (none yet) +- **privacy.astro SMS section** (legal, needs decision): the privacy policy has a full SMS-data-collection section (phone numbers, consent records, STOP/HELP, provider DPA), but there is NO phone/SMS collection anywhere on the website or in the product. Keep as forward-looking boilerplate, or remove until an SMS program ships? (Not touched — legal-commitment change.) + ## Pages | ledger | false | unverifiable | status | |---|---:|---:|---| | audit/docs/consent.md | 33 | 6 | done | | audit/for/compatibility.md | 16 | 33 | done | | audit/docs/enterprise-blueprints.md | 24 | 0 | done | -| audit/pages/privacy.md | 11 | 37 | todo | +| audit/pages/privacy.md | 11 | 37 | done | | audit/docs/cli-reference.md | 21 | 6 | done | | audit/docs/enterprise-identity.md | 22 | 0 | todo | | audit/blog/enterprise-production-complete-identity-directory-audit-export.md | 0 | 62 | todo | diff --git a/audit/pages/privacy.md b/audit/pages/privacy.md index 863e7ee..c525edc 100644 --- a/audit/pages/privacy.md +++ b/audit/pages/privacy.md @@ -58,3 +58,7 @@ Audited: 2026-07-10 · Sentences examined: 117 · verified: 62 · false: 11 · u - **git history (website repo)** — "Effective: May 28, 2026" matches initial legal-bundle commit 2026-05-28 (PILOT-25, PR #6); SMS sections added 2026-06-26 (#53). - **GDPR / CCPA legal texts** — Art. 6(1)(a)/(f) legal bases; rights articles 15/16/17/18/20/21/7(3)/77 all correctly mapped; Art. 22 automated decision-making, Art. 27/28/37 correctly cited; SCC instrument = Commission Implementing Decision (EU) 2021/914 + UK IDTA; response windows match GDPR Art. 12(3) (one month) and CCPA (45 days); CCPA right-to-know/delete/non-discrimination correctly stated. - **EXAMPLE values (not flagged)** — `v0.3.1` (illustrative daemon version; note: stale vs current v1.12.4), `agent-a` hostname, `production` / `us-east` tags. + +## Resolutions (2026-07-10, loop iteration 11) +FALSE (11): synthetic email corrected (first 6 bytes of pubkey → 12hex, not SHA-256; daemon.go:706-710); LAN IP reworded (collected unconditionally on UDP + sent to registry, not opt-in/peer-only; daemon.go:874,983); "never touches our infrastructure" qualified to direct-mode only (relay/compat transit beacons, still E2E encrypted); review prompts noted as behind a default-off feature flag; GA4 retention corrected (2 or 14 months option, user-level reset only); TLS 1.3 → "TLS 1.2 or higher" (MinVersion tls.VersionTLS12 at daemon.go:931/5900/5903); clear-email flow → pilotctl set-email (no clear-to-synthetic mechanism exists); last-updated bumped to July 10 2026 (sweep-4 changed the entity clause). GA4 consent-gating rows (62/98) resolved by PlainLayout GA4 removal → now true. +UNVERIFIABLE (37): Cloudflare Web Analytics VERIFIED live (beacon.min.js served, dashboard-injected) → accurate. Legal/practice declarations (DPAs, LIA, don't-sell, breach notice, children, DPO/Art.27 exemption, DPF certification, GDPR-compliance conclusion, CF/GA retention windows) → ACCEPTED as operator legal statements (not code-verifiable, not ours to invent). Flagged to needs-user: the SMS-collection section (§ describes visitor phone-number collection with no implementation anywhere on the site — decide keep-as-boilerplate vs remove). diff --git a/src/pages/privacy.astro b/src/pages/privacy.astro index c8db701..4af626f 100644 --- a/src/pages/privacy.astro +++ b/src/pages/privacy.astro @@ -22,7 +22,7 @@ const canonicalUrl = "https://pilotprotocol.network/privacy";

    Privacy Policy

    Pilot Protocol is operated by Vulture Labs, Inc., a Delaware corporation ("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").

    @@ -34,23 +34,23 @@ const canonicalUrl = "https://pilotprotocol.network/privacy";
    • IP address — Your public IP address, used for NAT traversal and peer discovery.
    • Daemon version — The version string of your running daemon binary (e.g., v0.3.1).
    • -
    • Synthetic email — A SHA-256 hash derived from your Ed25519 public key, used as an opaque identifier for the rendezvous registry when no real email is supplied.
    • -
    • Real email address (when supplied) — If you pass an email to the daemon (via the -email flag, email: field in ~/.pilot/config.json, or equivalent SDK option), we store and register that email in place of the synthetic one. It is used as your account identifier and for key-recovery flows (e.g. proving ownership during identity rotation). You may switch back to a synthetic identifier at any time by clearing the email field and re-registering — see "Your Rights" below.
    • +
    • Synthetic email — The first 6 bytes of your Ed25519 public key, hex-encoded as <12hex>@nodes.pilotprotocol.network, used as an opaque identifier for the rendezvous registry when no real email is supplied.
    • +
    • Real email address (when supplied) — If you pass an email to the daemon (via the -email flag, email: field in ~/.pilot/config.json, or equivalent SDK option), we store and register that email in place of the synthetic one. It is used as your account identifier and for key-recovery flows (e.g. proving ownership during identity rotation). You can set your own email at any time with pilotctl set-email; if you never set one, the synthetic identifier is used — see "Your Rights" below.
    • Hostname — The hostname you assign to your agent (e.g., agent-a).
    • Tags — Any tags you attach to your agent for group discovery (e.g., production, us-east).
    • Ed25519 public key — Your agent's cryptographic identity, used for authentication and establishing encrypted tunnels.
    • -
    • LAN IP address (optional) — If you enable local-network discovery, your private LAN IP is exchanged with peers on the same subnet.
    • +
    • LAN IP address — In UDP mode the daemon collects your private LAN IPv4 addresses and includes them in its registration with the rendezvous registry, so peers on the same subnet can connect directly.

    The data above does not include personal names, and — unless you explicitly supplied one via the -email flag — does not include an email address. The daemon does not log or transmit the payload of any peer-to-peer communication.

    -

    Important: 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.

    +

    Important: In direct peer-to-peer mode, traffic after tunnel establishment flows straight between agents and never touches our infrastructure. When a direct path isn't possible (relay or compat mode) traffic transits our beacon servers, but it stays end-to-end encrypted — we cannot see, log, or access its contents in any mode.

    2. Opt-Out Features

    Beyond core network operation, four features collect or act on additional data. All four are on by default (opt-out model) and can be disabled individually in ~/.pilot/config.json. None affect core messaging or peer routing when disabled.

    • App store telemetry — When you browse or install apps, a signed event (app ID + action) is sent to telemetry.pilotprotocol.network. No message contents or personal data. Disable: set consent.telemetry to false in ~/.pilot/config.json.
    • Broadcasts — Network administrators can send datagrams to all agents in a network. Requires a valid admin token on the sender's daemon. Disable: set consent.broadcasts to false in ~/.pilot/config.json.
    • -
    • Review prompts — Occasionally prompts you to leave a short review of Pilot or an app. Review text is sent to the telemetry endpoint when submitted. Disable: set consent.reviews to false in ~/.pilot/config.json.
    • +
    • Review prompts — The consent flag permits an occasional prompt to review Pilot or an app (the prompt itself is currently behind a feature flag that defaults off, so it does not appear on a default install). Review text is sent to the telemetry endpoint only if you submit one. Disable entirely: set consent.reviews to false in ~/.pilot/config.json.
    • Skill injection — The daemon writes SKILL.md and configuration directives into supported agent toolchains (Claude Code, OpenClaw, OpenHands, PicoClaw, Hermes) so those agents discover Pilot tools automatically. Disable or change the update mode via pilotctl skills set-mode disabled|manual|auto.

    See the Consent & Privacy Controls documentation page for full details, config format, and CLI commands for each feature.

    @@ -85,7 +85,7 @@ const canonicalUrl = "https://pilotprotocol.network/privacy";
  • Daemon registration data (IP, hostname, public key, tags, version) — Retained while your agent is registered. Automatically removed if the agent is offline for 30 consecutive days.
  • Phone number & SMS consent records — Retained while your number is enrolled to receive messages, and for a reasonable period afterward to evidence consent and opt-out as required by carrier rules and applicable law. Removed on request or after you opt out.
  • Server access logs — Retained for 30 days, then automatically deleted.
  • -
  • GA4 analytics data — Retention governed by Google's default settings (currently 14 months for event-level data, reset on each new visit).
  • +
  • GA4 analytics data — Retention is governed by our GA4 property's data-retention setting (Google offers 2 or 14 months); user-level data can be configured to reset on new activity. See Google's documentation for current specifics.
  • Cloudflare Web Analytics — Aggregated data retained for 30 days.
  • @@ -105,7 +105,7 @@ const canonicalUrl = "https://pilotprotocol.network/privacy";
  • Standard Contractual Clauses (SCCs) — EU Commission Implementing Decision 2021/914, plus the UK International Data Transfer Addendum.
  • EU-US Data Privacy Framework (DPF) — Google LLC and Cloudflare, Inc. are certified under the DPF.
  • -

    For jurisdictions without an adequacy decision, we implement supplementary measures including encryption at rest (AES-256) and in transit (TLS 1.3).

    +

    For jurisdictions without an adequacy decision, we implement supplementary measures including encryption at rest (AES-256) and in transit (TLS 1.2 or higher).

    9. Your Rights

    Depending on your jurisdiction, you may have the following rights:

    @@ -142,7 +142,7 @@ const canonicalUrl = "https://pilotprotocol.network/privacy";

    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.

    13. Security

    -

    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.

    +

    We implement appropriate technical and organizational measures to protect data: TLS (1.2 or higher) for control-plane transit, AES-256-GCM for encrypted peer 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.

    14. Changes to This Policy

    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.

    From d8c9c41984b7671606bb9e24dbf8f7bb55525395 Mon Sep 17 00:00:00 2001 From: Teodor Calin Date: Fri, 10 Jul 2026 22:24:33 +0300 Subject: [PATCH 19/75] audit-fix: docs/enterprise-identity (22 false resolved) Rewrote the identity/SSO/JWT/directory-sync docs to match rendezvous@v0.2.5: IDP is registry-global not per-network; RPC key 'type' not 'command'; provider field 'idp_type'; validate_token returns verified/subject/issuer; iat is not validated; JWKS refresh semantics; algorithm-confusion is blocked by JWKS key-type cross-check; directory sync matches by external_id, never adds members, owner is assignable, no tags; command directory_status. Co-Authored-By: Claude Fable 5 --- audit/PROGRESS.md | 2 +- audit/docs/enterprise-identity.md | 3 ++ src/pages/docs/enterprise-identity.astro | 59 ++++++++++++------------ 3 files changed, 33 insertions(+), 31 deletions(-) diff --git a/audit/PROGRESS.md b/audit/PROGRESS.md index 3417da4..0a81b4b 100644 --- a/audit/PROGRESS.md +++ b/audit/PROGRESS.md @@ -27,7 +27,7 @@ Started 2026-07-10. Status: todo | in-progress | done | blocked. | audit/docs/enterprise-blueprints.md | 24 | 0 | done | | audit/pages/privacy.md | 11 | 37 | done | | audit/docs/cli-reference.md | 21 | 6 | done | -| audit/docs/enterprise-identity.md | 22 | 0 | todo | +| audit/docs/enterprise-identity.md | 22 | 0 | done | | audit/blog/enterprise-production-complete-identity-directory-audit-export.md | 0 | 62 | todo | | audit/for/setups/[slug].md | 0 | 56 | todo | | audit/blog/zero-dependency-encryption-x25519-aes-gcm.md | 15 | 9 | todo | diff --git a/audit/docs/enterprise-identity.md b/audit/docs/enterprise-identity.md index 1224d6c..b8fde7a 100644 --- a/audit/docs/enterprise-identity.md +++ b/audit/docs/enterprise-identity.md @@ -50,3 +50,6 @@ version pinned by web4/go.mod. Abbreviated below as `rv/`. ## EXAMPLE (not flagged) - Placeholder values in all seven code blocks: `accounts.example.com`, `pilot-network-prod`, `your-admin-token`, `eyJhbGciOiJSUzI1NiIs...`, `auth.example.com`, `user@example.com`, `alice@example.com`, `bob@example.com`, node IDs 5/8, network_id 1. + +## Resolutions (2026-07-10, loop iteration 12) +All 22 FALSE resolved against rendezvous@v0.2.5 identity.go + directory_sync.go (re-verified): IDP is registry-global not per-network (single idpConfig field); RPC envelope key is "type" not "command" (8 blocks); provider type is "idp_type" not "type"; validate_token returns verified/subject/issuer not valid/claims; iat is never validated (removed from claim list + clock-skew); issuer matches configured issuer not URL; JWKS refresh only on TTL/URL-change/empty (missing kid in fresh cache errors); algorithm-confusion blocked via JWKS kty/alg cross-check not a configured alg; directory sync matches by external_id not node_id, never adds members (pre-assigns unmatched), owner IS assignable, no tags handling; command is directory_status not get_directory_status; status/audit return-key lists corrected. Removed node_id/tags from sync-entry example (kept node_id in set_external_id/get_identity where it's valid). diff --git a/src/pages/docs/enterprise-identity.astro b/src/pages/docs/enterprise-identity.astro index d6ac99d..8f1b8c5 100644 --- a/src/pages/docs/enterprise-identity.astro +++ b/src/pages/docs/enterprise-identity.astro @@ -23,7 +23,7 @@ const bodyContent = `

    Identity & SSO

    Enterprise networks can integrate with external identity providers (IDPs) to centralize authentication. Instead of relying solely on Pilot’s built-in Ed25519 keys, agents can present tokens from your organization’s IDP - OIDC, SAML, Entra ID, LDAP, or a custom webhook - and the registry validates them before granting access.

    -

    Identity integration is per-network. Each network can have its own IDP configuration, allowing different teams or environments to use different providers.

    +

    Identity integration is registry-global: a single IDP configuration applies across the registry, and setting a new one replaces the previous config. (Blueprint provisioning writes the same global store.)

    Supported providers

    @@ -44,8 +44,8 @@ const bodyContent = `

    Identity & SSO

    # OIDC example
     {
    -  "command": "set_idp_config",
    -  "type": "oidc",
    +  "type": "set_idp_config",
    +  "idp_type": "oidc",
       "url": "https://accounts.example.com/.well-known/openid-configuration",
       "client_id": "pilot-network-prod",
       "admin_token": "your-admin-token"
    @@ -56,7 +56,7 @@ const bodyContent = `

    Identity & SSO

    To query the current configuration:

    {
    -  "command": "get_idp_config",
    +  "type": "get_idp_config",
       "admin_token": "your-admin-token"
     }
    @@ -77,12 +77,12 @@ const bodyContent = `

    Identity & SSO

    Validate a token with the validate_token protocol command:

    {
    -  "command": "validate_token",
    +  "type": "validate_token",
       "token": "eyJhbGciOiJSUzI1NiIs...",
       "admin_token": "your-admin-token"
     }
    -

    Returns: valid (bool), claims (the decoded JWT claims if valid), or error (string describing why validation failed).

    +

    Returns: verified (bool), subject (the token subject), issuer, and — on failure — error (string describing why validation failed).

    Validated claims

    @@ -92,8 +92,8 @@ const bodyContent = `

    Identity & SSO

  • Signature - verified against the JWKS public key (RS256) or shared secret (HS256)
  • Expiration (exp) - token must not be expired
  • Not-before (nbf) - token must not be used before its valid time
  • -
  • Issued-at (iat) - checked for reasonableness
  • -
  • Issuer (iss) - must match the configured IDP URL
  • + +
  • Issuer (iss) - must match the configured issuer value, when one is set
  • Audience (aud) - must match the configured client ID
  • @@ -107,7 +107,7 @@ const bodyContent = `

    Identity & SSO

    Cache TTL5 minutes Max response size64 KB Key matchingBy kid (Key ID) header in the JWT - RefreshAutomatic on cache expiry; on-demand if kid not found in cached set + RefreshOn TTL expiry, URL change, or empty cache. A kid missing from a fresh (non-expired) cache returns an error rather than refetching. @@ -117,11 +117,11 @@ const bodyContent = `

    Identity & SSO

    Algorithm confusion prevention

    -

    The validator enforces the expected algorithm based on configuration. If the IDP is configured with RS256, an attacker cannot present an HS256 token signed with the public key (a classic algorithm confusion attack). The alg header in the JWT must match the configured algorithm.

    +

    The validator blocks the classic algorithm-confusion attack by cross-checking the JWT's alg header against the matched JWKS key's own type (RSA for RS256, oct for HS256) — an HS256 token cannot be verified against an RSA signing key. There is no separately-configured algorithm; RS256 and HS256 are the two supported algorithms.

    Clock skew tolerance

    -

    A 60-second clock skew tolerance is applied to all time-based claims (exp, nbf, iat). This accommodates minor clock differences between the IDP and the registry without opening a significant window for expired tokens.

    +

    A 60-second clock skew tolerance is applied to the time-based claims that are checked (exp and nbf). This accommodates minor clock differences between the IDP and the registry without opening a significant window for expired tokens.

    Webhook identity

    @@ -129,8 +129,8 @@ const bodyContent = `

    Identity & SSO

    # Configure a webhook IDP
     {
    -  "command": "set_idp_config",
    -  "type": "webhook",
    +  "type": "set_idp_config",
    +  "idp_type": "webhook",
       "url": "https://auth.example.com/verify-agent",
       "admin_token": "your-admin-token"
     }
    @@ -143,7 +143,7 @@ const bodyContent = `

    Identity & SSO

    # Set an external ID for an agent
     {
    -  "command": "set_external_id",
    +  "type": "set_external_id",
       "node_id": 5,
       "external_id": "user@example.com",
       "admin_token": "your-admin-token"
    @@ -151,7 +151,7 @@ const bodyContent = `

    Identity & SSO

    # Look up an agent’s identity { - "command": "get_identity", + "type": "get_identity", "node_id": 5, "admin_token": "your-admin-token" }
    @@ -160,23 +160,22 @@ const bodyContent = `

    Identity & SSO

    Directory sync

    -

    Directory sync pushes entries from an external directory (AD, Entra ID, LDAP) to the registry, automatically provisioning and deprovisioning network members.

    +

    Directory sync pushes entries from an external directory (AD, Entra ID, LDAP) to the registry. It updates roles for existing members, removes members no longer in the directory, and stores role pre-assignments for identities that have not joined yet — it does not itself add (join) new members.

    Sync operation

    {
    -  "command": "directory_sync",
    +  "type": "directory_sync",
       "network_id": 1,
       "entries": [
         {
           "external_id": "alice@example.com",
    -      "node_id": 5,
    -      "role": "admin",
    -      "tags": ["frontend", "us-east"]
    +      "display_name": "Alice",
    +      "role": "admin"
         },
         {
           "external_id": "bob@example.com",
    -      "node_id": 8,
    +      "display_name": "Bob",
           "role": "member"
         }
       ],
    @@ -187,29 +186,29 @@ const bodyContent = `

    Identity & SSO

    What sync does

      -
    1. Matches entries - each entry is matched to a registered node by node_id
    2. -
    3. Joins to network - nodes not already in the network are added
    4. -
    5. Maps roles - the role field sets the RBAC role (admin or member). Owner role cannot be assigned through sync.
    6. -
    7. Sets external IDs - the external_id field is stored for identity mapping
    8. -
    9. Applies tags - optional tags field sets the node’s capability tags
    10. +
    11. Matches entries - each entry is matched to an existing member by normalized external_id
    12. +
    13. Pre-assigns unmatched - entries with no matching member are counted as unmapped and stored as role pre-assignments applied when that identity later joins
    14. +
    15. Maps roles - the role field sets the RBAC role; owner, admin, and member are all assignable.
    16. +
    17. Reads external IDs - the external_id field is used to match; the node must already carry an external ID (set via set_external_id or at register) to be matched
    18. +
    19. Removes unlisted - if remove_unlisted is true, members not in the entries list are kicked from the network

    RBAC pre-assignments

    -

    Directory sync supports role pre-assignment: when a new member is added through sync, they receive their assigned role immediately instead of defaulting to member. This is useful for provisioning admin roles in bulk.

    +

    Directory sync supports role pre-assignment: an identity not yet in the network gets its assigned role stored, so when the matching node later joins it receives that role instead of defaulting to member. This is useful for provisioning admin roles in bulk.

    Query sync status

    {
    -  "command": "get_directory_status",
    +  "type": "directory_status",
       "network_id": 1,
       "admin_token": "your-admin-token"
     }
    -

    Returns the last sync timestamp, number of entries processed, and any errors encountered.

    +

    Returns network_id, total, mapped, unmapped, pre_assignments, enterprise, and last_sync.

    -

    A directory.synced audit event is emitted after each sync, recording the network ID, number of entries added, removed, and role changes.

    +

    A directory.synced audit event is emitted after each sync, recording the network ID and the mapped, updated, disabled, and unmapped counts.

    See also: RBAC & Access Control - role definitions and the permissions matrix. Blueprints - include IDP configuration in declarative provisioning. From 8247051be0e70c38cb3602768b41625684eef2a6 Mon Sep 17 00:00:00 2001 From: Teodor Calin Date: Fri, 10 Jul 2026 22:28:05 +0300 Subject: [PATCH 20/75] audit-fix: enterprise-production blog (62 unverifiable resolved, historical) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Historical enterprise-production announcement — self-reported metrics accepted as point-in-time claims; technical details cross-verified consistent against rendezvous@v0.2.5 (IDP-global, JWT iss/aud/exp/nbf omitting iat, directory sync semantics, audit formats + DLQ, /metrics). 0 false, no page edit. Co-Authored-By: Claude Fable 5 --- audit/PROGRESS.md | 2 +- ...rise-production-complete-identity-directory-audit-export.md | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/audit/PROGRESS.md b/audit/PROGRESS.md index 0a81b4b..a85f3b7 100644 --- a/audit/PROGRESS.md +++ b/audit/PROGRESS.md @@ -28,7 +28,7 @@ Started 2026-07-10. Status: todo | in-progress | done | blocked. | audit/pages/privacy.md | 11 | 37 | done | | audit/docs/cli-reference.md | 21 | 6 | done | | audit/docs/enterprise-identity.md | 22 | 0 | done | -| audit/blog/enterprise-production-complete-identity-directory-audit-export.md | 0 | 62 | todo | +| audit/blog/enterprise-production-complete-identity-directory-audit-export.md | 0 | 62 | done | | audit/for/setups/[slug].md | 0 | 56 | todo | | audit/blog/zero-dependency-encryption-x25519-aes-gcm.md | 15 | 9 | todo | | audit/blog/github-com-alternatives-6.md | 3 | 43 | todo | diff --git a/audit/blog/enterprise-production-complete-identity-directory-audit-export.md b/audit/blog/enterprise-production-complete-identity-directory-audit-export.md index 2482b24..c5e56ee 100644 --- a/audit/blog/enterprise-production-complete-identity-directory-audit-export.md +++ b/audit/blog/enterprise-production-complete-identity-directory-audit-export.md @@ -28,3 +28,6 @@ The registry SERVER source is not present in the local checkout (web4/pkg contai - Local site files: /docs/getting-started, /docs/networks, /plans pages exist; banner webp exists - Frontmatter/meta description: restates in-body claims (counted once above) - EXAMPLE: all JSON request/response payloads (set_idp_config, directory_sync, blueprint, DLQ, provision result) — illustrative sample values + +## Resolutions (2026-07-10, loop iteration 13) +0 FALSE. This is a dated enterprise-production announcement post; per the blog rule, self-reported point-in-time metrics (99 features / 53 commands / 234 tests / 40+ metrics / per-file test table) → ACCEPTED (historical announcement — the author's claims about their registry at ship time; registry server repo not in local modules to re-derive counts). The technical claims WERE cross-verified against rendezvous@v0.2.5 (auditor lacked this source) and are consistent: IDP config is per-registry/global (identity.go idpConfig single field); JWT claims validated iss/aud/exp/nbf with the post correctly OMITTING iat (jwtClockSkew applies to Expiry only, identity.go:891,912); RS256/HS256 only; directory sync updates roles / disables / removes-unlisted / pre-assigns (does NOT claim to add members — more accurate than the docs page was); audit formats splunk_hec+json and webhook DLQ confirmed (replication.go:414, server_handlers.go:112); /metrics endpoint exists; dispatch.go has 59 command entries (post's "53" plausible for an earlier version). No misleading present-tense technical claim found. No page edit. From 8201cffdd91b58ede4edd702f2f804108c6c4d55 Mon Sep 17 00:00:00 2001 From: Teodor Calin Date: Fri, 10 Jul 2026 22:32:20 +0300 Subject: [PATCH 21/75] audit-fix: docs/service-agents (16 false resolved) Verified against the private pilot-agents repo (authenticated gh): search is semantic (substring+fuzzy+embeddings) not literal token match; truncation is agent-side not daemon; responder is event-driven not polling; real flag names (-endpoints/-pilotctl/-inbox-dir); messages accept plain /slash or JSON (not JSON-only), prose is dropped; scaffold is template/ in the (private) pilot-agents repo not service-agents/. Flagged the private-repo + stale-skill items to needs-user. Co-Authored-By: Claude Fable 5 --- audit/PROGRESS.md | 4 +++- audit/docs/service-agents.md | 3 +++ src/pages/docs/service-agents.astro | 35 +++++++++++++++-------------- 3 files changed, 24 insertions(+), 18 deletions(-) diff --git a/audit/PROGRESS.md b/audit/PROGRESS.md index a85f3b7..701a3e2 100644 --- a/audit/PROGRESS.md +++ b/audit/PROGRESS.md @@ -19,6 +19,8 @@ Started 2026-07-10. Status: todo | in-progress | done | blocked. - **privacy.astro SMS section** (legal, needs decision): the privacy policy has a full SMS-data-collection section (phone numbers, consent records, STOP/HELP, provider DPA), but there is NO phone/SMS collection anywhere on the website or in the product. Keep as forward-looking boilerplate, or remove until an SMS program ships? (Not touched — legal-commitment change.) +- **pilot-agents repo is private** (needs decision): docs/service-agents tells readers to `cp -r pilot-agents/template` but the repo is access-gated — make it public, or keep the "reach out for access" framing I added? Also the injected pilotctl skill (TeoSlayer/pilot-skills) still says search is "literal token match" — it is actually semantic; worth updating that skill repo too. + ## Pages | ledger | false | unverifiable | status | |---|---:|---:|---| @@ -32,7 +34,7 @@ Started 2026-07-10. Status: todo | in-progress | done | blocked. | audit/for/setups/[slug].md | 0 | 56 | todo | | audit/blog/zero-dependency-encryption-x25519-aes-gcm.md | 15 | 9 | todo | | audit/blog/github-com-alternatives-6.md | 3 | 43 | todo | -| audit/docs/service-agents.md | 16 | 0 | todo | +| audit/docs/service-agents.md | 16 | 0 | done | | audit/blog/lightweight-swarm-communication-drones-robots.md | 9 | 20 | todo | | audit/docs/tags.md | 15 | 2 | todo | | audit/docs/gateway.md | 15 | 1 | todo | diff --git a/audit/docs/service-agents.md b/audit/docs/service-agents.md index 62c6cdd..0b6830a 100644 --- a/audit/docs/service-agents.md +++ b/audit/docs/service-agents.md @@ -38,3 +38,6 @@ Audited: 2026-07-10 · Sentences examined: 125 · verified: 98 · false: 16 · u - Line 104 `-socket` row: flag exists in the Go responder but its default is derived from the pilotctl path (dirname(dirname(pilotctl))/pilot.sock), described in-source as "NEVER /tmp/pilot.sock" — "daemon default" is acceptable but could be more precise. The Python responder has no socket flag. - Lines 176/180/218: beyond the wrong paths, the scaffold repo (pilot-protocol/pilot-agents) is private (gh api .private == true), so readers cannot copy it at all as documented. - Examples counted: endpoints.yaml sample block (L112-123), SYSTEM_PROMPT snippet (L196-199), my-agent endpoints entry (L205-207), `cd my-agent`, localhost:8300/audit diagram label. + +## Resolutions (2026-07-10, loop iteration 14) +All 16 FALSE resolved — verified against the private pilot-protocol/pilot-agents repo via authenticated gh api: search.py is a 4-strategy ranker (substring + fuzzy Levenshtein + doc/category embeddings, semantic — "aviation"→flights), NOT literal token match; truncation is agent-side _format_json(limit=8000) in api/server.py, not the daemon transport; responder is event-driven (main.go "event-driven, fork-free"; no interval flag), not polling; real flags -endpoints/-pilotctl/-socket/-inbox-dir (not -config/-interval); dispatch.go accepts plain /slash text OR {"command","body"} JSON (JSON not required), non-slash prose → ActionDroppedText (so the "Hello from another node" example was dropped → changed to /help --wait); scaffold is template/ in pilot-agents (private — added access-gated note), not service-agents/ in the main repo; config.yaml is name/description/port (no endpoint path); clawdit at agents/clawdit/api/server.py not service-agents/examples/claw-audit. Side-note: the injected pilotctl skill (TeoSlayer/pilot-skills) also carries the stale "literal token match" line — separate repo, flagged. diff --git a/src/pages/docs/service-agents.astro b/src/pages/docs/service-agents.astro index 218ebe6..b45df23 100644 --- a/src/pages/docs/service-agents.astro +++ b/src/pages/docs/service-agents.astro @@ -72,12 +72,12 @@ const bodyContent = `

    Service Agents

    # Full directory
     pilotctl send-message list-agents --data '/data' --wait
     
    -# Keyword-filtered (search is literal token match, not semantic)
    +# Keyword-filtered (ranked: substring + fuzzy + semantic embeddings)
     pilotctl send-message list-agents --data '/data {"search":"bitcoin","limit":10}' --wait
     
     jq -r '.data' "$(ls -1t ~/.pilot/inbox/*.json | head -1)"
    -

    Use short, generic, single-word keywords (bitcoin, weather, nba, iss) — search matches tokens in agent names and descriptions, so multi-word phrases rarely improve recall.

    +

    Keywords work well (bitcoin, weather, nba, iss), and the ranker also matches semantically — a query like aviation can surface flight agents with no literal token overlap. It scores each agent by substring, fuzzy (Levenshtein), and embedding similarity over name/category/description.

    Once you know an agent's name, call it the same way:

    pilotctl handshake <agent-name>
    @@ -86,22 +86,23 @@ const bodyContent = `

    Service Agents

    jq -r '.data' "$(ls -1t ~/.pilot/inbox/*.json | head -1)"
    - Reply truncation: the daemon transport caps each inbox reply at roughly 8–9 KB, splicing ... (truncated, N bytes total) into the JSON value mid-stream. For specialists that may return more than that (full directory dumps, scoreboards, large lists), always pass a limit filter or use /summary for a synthesised digest. + Reply truncation: the specialist's own API server caps each reply at roughly 8 KB, splicing ... (truncated, N bytes total) into the JSON value. For specialists that may return more than that (full directory dumps, scoreboards, large lists), always pass a limit filter or use /summary for a synthesised digest.

    Responder

    -

    The responder is the daemon that makes service agents work. It runs on the node where your agents are hosted, continuously polling the pilot inbox for incoming messages, dispatching them to the correct local HTTP service, and sending replies back through the overlay.

    +

    The responder is the daemon that makes service agents work. It runs on the node where your agents are hosted, watching the pilot inbox (event-driven, not polling) for incoming messages, dispatching them to the correct local HTTP service, and sending replies back through the overlay.

    Usage

    -
    responder [-config <path>] [-interval <duration>] [-socket <path>]
    +
    responder [-endpoints <path>] [-pilotctl <path>] [-socket <path>] [-inbox-dir <path>] [-history <path>]
    - - - + + + +
    FlagDefaultDescription
    -config <path>~/.pilot/endpoints.yamlPath to the endpoints configuration file
    -interval <duration>5sHow often to poll the inbox (e.g. 5s, 10s, 1m)
    -socket <path>daemon defaultPilot daemon socket path
    -endpoints <path>~/.pilot/endpoints.yamlPath to the endpoints configuration file
    -pilotctl <path>~/.pilot/bin/pilotctlpilotctl path (used to derive the daemon socket)
    -socket <path>derived from -pilotctlPilot daemon socket path
    -inbox-dir <path>~/.pilot/inboxInbox directory the daemon writes to
    @@ -133,10 +134,10 @@ commands:

    Message format

    -

    Incoming messages must be JSON:

    +

    The responder accepts two message forms: plain text starting with / (e.g. /help, /data {...}), or a JSON wrapper:

    {"command": "<name>", "body": "<args>"}
    -

    The responder matches the command field against the configured endpoints. If arg_regex is set, the body is validated against it and named capture groups are forwarded as query parameters to the backing service. If the body doesn't match the regex, the message is rejected.

    +

    The responder matches the command (the slash word, or the command field) against the configured endpoints. If arg_regex is set, named capture groups from the body are forwarded as query parameters to the backing service; if the body doesn't match, it dispatches with no captured params (it is not rejected). Plain prose with no leading / is dropped, to prevent reply loops.

    Request–reply cycle

      @@ -157,7 +158,7 @@ commands: │ ▼ overlay encrypted (X25519 + AES-256-GCM) responder on service agent node - │ polls ~/.pilot/inbox/ every 5s + │ watches ~/.pilot/inbox/ (event-driven) │ parses JSON → matches command → validates arg_regex ▼ localhost HTTP service (e.g. http://localhost:8300/audit) @@ -173,19 +174,19 @@ commands:

      Building your own agent

      -

      The service-agents/ directory in the Pilot Protocol repository contains a scaffold and examples you can copy.

      +

      The template/ directory in the pilot-protocol/pilot-agents repository is a scaffold you can copy (the repo is currently access-gated — reach out for access).

      1. Scaffold a new agent

      -
      cp -r service-agents/template my-agent
      +  
      cp -r pilot-agents/template my-agent
       cd my-agent

      The template includes:

      • start.sh - creates a virtualenv, installs deps, starts the FastAPI server
      • requirements.txt - Python dependencies
      • -
      • config.yaml - agent name, port, and endpoint path
      • -
      • api/server.py - FastAPI app (chat or stateless audit endpoint)
      • +
      • config.yaml - agent name, description, and port (the endpoint path is derived from the name)
      • +
      • api/server.py - FastAPI app exposing your data endpoint and /health
      • agent/gemini_agent.py - Gemini AI agent base class
      • agent/prompts.py - system prompt
      • agent/tools.py - tool definitions
      • @@ -213,9 +214,9 @@ You are MyAgent, a specialized assistant that...

        5. Call it from any trusted node

        -
        pilotctl send-message my-agent --data "Hello from another node"
        +
        pilotctl send-message my-agent --data '/help' --wait
        -

        For multi-turn conversation support, implement a /sessions API following the pattern in service-agents/examples/claw-audit/api/server.py.

        +

        For multi-turn conversation support, implement a /sessions API following the pattern in the clawdit agent (agents/clawdit/api/server.py) in the pilot-agents repo.

        Further reading: HTTP services over the encrypted overlay From 633bf02469f3a2988b8c03de6560fc7c61c99773 Mon Sep 17 00:00:00 2001 From: Teodor Calin Date: Fri, 10 Jul 2026 22:35:26 +0300 Subject: [PATCH 22/75] audit-fix: for/setups/[slug] (56 unverifiable resolved + meta bug) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 0 false. The 56 unverifiable rows are one class — per-setup efficacy ledes sourced from the catalog data (structurally verified) → accepted as catalog content. Fixed the flagged quality bug: meta description was setup.tagline (a mid-word ~100-char cut on 40/56 pages) → clean word-boundary truncation of the full description. Co-Authored-By: Claude Fable 5 --- audit/PROGRESS.md | 2 +- audit/for/setups/[slug].md | 3 +++ src/pages/for/setups/[slug].astro | 7 ++++++- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/audit/PROGRESS.md b/audit/PROGRESS.md index 701a3e2..1a5d33e 100644 --- a/audit/PROGRESS.md +++ b/audit/PROGRESS.md @@ -31,7 +31,7 @@ Started 2026-07-10. Status: todo | in-progress | done | blocked. | audit/docs/cli-reference.md | 21 | 6 | done | | audit/docs/enterprise-identity.md | 22 | 0 | done | | audit/blog/enterprise-production-complete-identity-directory-audit-export.md | 0 | 62 | done | -| audit/for/setups/[slug].md | 0 | 56 | todo | +| audit/for/setups/[slug].md | 0 | 56 | done | | audit/blog/zero-dependency-encryption-x25519-aes-gcm.md | 15 | 9 | todo | | audit/blog/github-com-alternatives-6.md | 3 | 43 | todo | | audit/docs/service-agents.md | 16 | 0 | done | diff --git a/audit/for/setups/[slug].md b/audit/for/setups/[slug].md index dfff290..db06bd3 100644 --- a/audit/for/setups/[slug].md +++ b/audit/for/setups/[slug].md @@ -27,3 +27,6 @@ This is a dynamic template that renders 56 org-setup pages from an external cata ## Opinion (not flagged) - L113 CTA "Ready to deploy {name}?" — marketing prompt, no factual content. + +## Resolutions (2026-07-10, loop iteration 15) +0 FALSE. The 56 UNVERIFIABLE flags are all one class — each setup's efficacy lede ("automate campaign strategy…") sourced from the catalog data (TeoSlayer/pilot-skills setups.json); the structural half (agent count/roles/skills/flows) was verified consistent, and the efficacy framing is the catalog author's claim, not website-invented → ACCEPTED (catalog-sourced; can't deploy 56 setups to test each workflow). FIXED the real quality bug the auditor flagged: meta description used setup.tagline (a hard ~100-char cut breaking mid-word on 40/56 pages) → now a clean word-boundary truncation of setup.description (≤155 chars). Build green. diff --git a/src/pages/for/setups/[slug].astro b/src/pages/for/setups/[slug].astro index 98fd85f..e5ba62c 100644 --- a/src/pages/for/setups/[slug].astro +++ b/src/pages/for/setups/[slug].astro @@ -19,7 +19,12 @@ export async function getStaticPaths() { const { setup } = Astro.props as { setup: any }; const title = `${setup.name} - Orgs · Pilot Protocol`; -const description = setup.tagline; +// Meta description: clean word-boundary truncation of the full description +// (setup.tagline is a hard ~100-char cut that breaks mid-word). +const rawDesc: string = setup.description || setup.tagline || ''; +const description = rawDesc.length > 155 + ? rawDesc.slice(0, 155).replace(/\s+\S*$/, '') + '…' + : rawDesc; const canonicalUrl = `https://pilotprotocol.network/for/setups/${setup.slug}`; --- From 36315b5286cff80b49395f5df7edafb5050a4752 Mon Sep 17 00:00:00 2001 From: Teodor Calin Date: Fri, 10 Jul 2026 22:41:27 +0300 Subject: [PATCH 23/75] audit-fix: zero-dependency-encryption blog (15 false, 9 unverifiable) Corrected the crypto explainer to shipped web4 behavior: AES key is HKDF-SHA256-derived not raw ECDH (a documented H1 fix the blog predated); X25519 keypair is per-daemon not per-tunnel (reframed forward-secrecy -> peer isolation with honest caveat); encryption is the global -encrypt default not port-443-gated; PILK 40B/dir (80 total), PILS overhead 36B; WireGuard keys are 256-bit. Softened unbenchmarked perf/line-count figures. Co-Authored-By: Claude Fable 5 --- audit/PROGRESS.md | 2 +- ...ro-dependency-encryption-x25519-aes-gcm.md | 3 ++ ...dependency-encryption-x25519-aes-gcm.astro | 43 ++++++++++--------- 3 files changed, 26 insertions(+), 22 deletions(-) diff --git a/audit/PROGRESS.md b/audit/PROGRESS.md index 1a5d33e..b35759f 100644 --- a/audit/PROGRESS.md +++ b/audit/PROGRESS.md @@ -32,7 +32,7 @@ Started 2026-07-10. Status: todo | in-progress | done | blocked. | audit/docs/enterprise-identity.md | 22 | 0 | done | | audit/blog/enterprise-production-complete-identity-directory-audit-export.md | 0 | 62 | done | | audit/for/setups/[slug].md | 0 | 56 | done | -| audit/blog/zero-dependency-encryption-x25519-aes-gcm.md | 15 | 9 | todo | +| audit/blog/zero-dependency-encryption-x25519-aes-gcm.md | 15 | 9 | done | | audit/blog/github-com-alternatives-6.md | 3 | 43 | todo | | audit/docs/service-agents.md | 16 | 0 | done | | audit/blog/lightweight-swarm-communication-drones-robots.md | 9 | 20 | todo | diff --git a/audit/blog/zero-dependency-encryption-x25519-aes-gcm.md b/audit/blog/zero-dependency-encryption-x25519-aes-gcm.md index 8699725..494ad29 100644 --- a/audit/blog/zero-dependency-encryption-x25519-aes-gcm.md +++ b/audit/blog/zero-dependency-encryption-x25519-aes-gcm.md @@ -41,3 +41,6 @@ Audited: 2026-07-10 · Sentences examined: 96 · verified: 62 · false: 15 · un - cmd/pilotctl/main.go:896,1488: `pilotctl connect [port] [--message ]` exists as shown in the terminal example (output text is illustrative) - RFCs/public knowledge: RFC 7748 (X25519/Curve25519 ECDH), RFC 5288 (AES-GCM TLS suites), TLS 1.3 uses AES-GCM & mandates TLS_AES_128_GCM_SHA256 (RFC 8446), GCM = confidentiality+integrity, 16-byte GCM tag, nonce-reuse keystream attack, AES rounds 10 (128-bit) vs 14 (256-bit) per FIPS 197, aes.NewCipher selects variant by key length (Go docs), AES-NI since ~2010 / ARMv8 crypto extensions, Heartbleed (2014 OpenSSL buffer over-read), xz Utils backdoor (2024), OpenSSL >500k lines of C, DTLS exists for UDP, TLS certificate/X.509 lifecycle descriptions, 2^64 counter capacity - Pre-verified + local files: github.com/pilot-protocol/pilotprotocol exists; internal blog links (nat-traversal-ai-agents-deep-dive, secure-ai-agent-communication-zero-trust, how-pilot-protocol-works, secure-research-collaboration-share-models-not-data, private-agent-network-company, overlay-network-ai-agents) all exist in src/pages/blog; banner webp exists; single static Go binary claim consistent with installer distribution + +## Resolutions (2026-07-10, loop iteration 16) +All 15 FALSE + 9 UNVERIFIABLE resolved. This is a present-tense technical explainer (not a dated announcement), so corrected to shipped crypto verified in web4: AES key is HKDF-SHA256(shared, info="pilot-tunnel-v1") NOT raw ECDH (keyexchange/derive.go:44-56 — a documented "H1 fix" the blog predated); X25519 keypair is generated ONCE at daemon startup and reused (tunnel.go:524-526), not per-tunnel — reframed forward-secrecy claims to "peer isolation" with an honest per-daemon-lifetime caveat; encryption is the global -encrypt default (main.go:65), NO port-443 gating; PILK frame is 40 bytes/direction (frame.go:19, 4+4+32), 80 total not 72; PILS overhead 36 bytes not 32 (adds 4-byte sender nodeID); PILT has no length field (UDP framing); WireGuard uses 256-bit ChaCha20-Poly1305 keys not 128-bit; 1024-byte overhead 3.5% not 3.1%. UNVERIFIABLE: line-count/benchmark figures softened (stdlib counts were understated; 0.3ms "cross-region measured" was implausible → reframed as sub-ms compute + RTT-bound; added "illustrative, not benchmarked" caveat to the perf table). diff --git a/src/pages/blog/zero-dependency-encryption-x25519-aes-gcm.astro b/src/pages/blog/zero-dependency-encryption-x25519-aes-gcm.astro index e198a90..d8339e7 100644 --- a/src/pages/blog/zero-dependency-encryption-x25519-aes-gcm.astro +++ b/src/pages/blog/zero-dependency-encryption-x25519-aes-gcm.astro @@ -25,7 +25,7 @@ const bodyContent = `

        Pilot Protocol implements its entire encryption stack --

        External crypto libraries often pull in hundreds of thousands of lines of code. OpenSSL alone is over 500,000 lines of C. Auditing this is a multi-year, multi-million-dollar effort that most organizations never complete.

        -

        Go's crypto/ecdh package for X25519 is roughly 300 lines of Go. The crypto/aes and crypto/cipher packages for AES-GCM add another ~1,500 lines. The total audit surface for Pilot's encryption is under 2,000 lines of well-documented, type-safe Go code. A single security engineer can review it in a day.

        +

        Pilot's encryption relies only on Go's standard-library crypto/ecdh, crypto/aes, crypto/cipher, and crypto/sha256 — a few thousand lines of well-documented, type-safe, widely-reviewed Go, with no third-party cryptography dependencies to audit.

        Reproducible Builds

        @@ -41,7 +41,7 @@ const bodyContent = `

        Pilot Protocol implements its entire encryption stack --

        How It Works

        -

        When two Pilot agents establish a tunnel, each side generates an ephemeral X25519 key pair. "Ephemeral" means the keys are created fresh for every tunnel establishment. Even if an attacker captures and decrypts one session's traffic (by somehow obtaining the shared secret), they cannot decrypt any other session because every session uses different keys. This property is called forward secrecy.

        +

        When a Pilot daemon enables encryption it generates an X25519 key pair once at startup and reuses it for the tunnels it establishes. Each pair of peers derives a distinct shared secret from their two public keys, so a peer cannot read traffic between two other peers. (Note: because the X25519 key is per-daemon-lifetime rather than per-session, this is not per-session forward secrecy — a future rotating-key design would add that.)

        // Generate ephemeral X25519 key pair using Go's crypto/ecdh
         curve := ecdh.X25519()
        @@ -55,7 +55,8 @@ privateKey, err := curve.GenerateKey(rand.Reader)
         
         // Derive shared secret using ECDH
         sharedSecret, err := privateKey.ECDH(peerPublicKey)
        -// sharedSecret is 32 bytes -- used as the AES-256 key
        +// sharedSecret (32 bytes) is run through HKDF-SHA256 +// (info = "pilot-tunnel-v1") to derive the AES-256-GCM key

      The mathematics of elliptic curve Diffie-Hellman guarantee that both sides derive the same shared secret, even though neither transmitted their private key. An eavesdropper who captures both public keys cannot derive the shared secret without solving the elliptic curve discrete logarithm problem, which is computationally infeasible.

      @@ -79,9 +80,9 @@ Agent A Agent B |<========= PILS encrypted traffic ==============>| # PILK = 0x50494C4B ("Pilot Key"), 4 bytes magic + 32 bytes public key -# Total key exchange overhead: 72 bytes (36 bytes per direction)
    +# PILK frame: 4 magic + 4 nodeID + 32 pubkey = 40 bytes/direction (80 total)
    -

    The entire key exchange adds approximately 0.3ms to connection setup time. This is measured on cross-region connections between GCP VMs. On local networks, key exchange completes in under 0.1ms. The cost is paid once per tunnel, not per packet.

    +

    The X25519 computation itself is sub-millisecond; the dominant setup cost is the one network round-trip for the handshake, which is bounded by the peers' RTT. The crypto cost is paid once per tunnel, not per packet.

    AES-256-GCM: Authenticated Encryption

    @@ -115,18 +116,18 @@ plaintext, err := aesGCM.Open(nil, nonce, ciphertext, nil)
    # PILT frame (plaintext, used before key exchange)
     50 49 4C 54    # Magic: "PILT"
    -XX XX          # Frame length
    -[pilot packet] # 34-byte header + payload (plaintext)
    +[pilot packet] # header + payload (plaintext; UDP datagram framing, no length field)
     
     # PILS frame (encrypted, used after key exchange)
     50 49 4C 53    # Magic: "PILS"
    +[4 bytes]      # Sender nodeID (big-endian)
     [12 bytes]     # Nonce (4-byte random prefix + 8-byte counter)
     [N bytes]      # AES-256-GCM ciphertext
     [16 bytes]     # GCM authentication tag (appended by Seal)
     
    -# Overhead per packet: 4 (magic) + 12 (nonce) + 16 (auth tag) = 32 bytes
    +# Overhead per packet: 4 (magic) + 4 (nodeID) + 12 (nonce) + 16 (auth tag) = 36 bytes -

    The 32-byte overhead per packet is modest. For a typical agent message of 1,024 bytes, encryption adds 3.1% overhead. For larger payloads near the MTU limit, overhead drops below 2%. The per-packet encryption time is approximately 5 microseconds on modern hardware -- negligible compared to network latency.

    +

    The 36-byte overhead per packet is modest. For a typical agent message of 1,024 bytes, encryption adds about 3.5% overhead. For larger payloads near the MTU limit, overhead drops below 2%. The per-packet encryption time is approximately 5 microseconds on modern hardware -- negligible compared to network latency.

    Nonce Management: Preventing Replay and Reuse

    @@ -195,7 +196,7 @@ Agent A Agent B | Authentication tags prevent tampering | Counter nonces prevent replay -

    The entire handshake adds one round-trip (~0.3ms on typical networks). After the handshake, every packet is encrypted and authenticated with ~5 microseconds of overhead. The agent developer never calls any encryption API -- the daemon handles it automatically when connections target port 443 or when encrypt-by-default is enabled.

    +

    The entire handshake adds one round-trip (~0.3ms on typical networks). After the handshake, every packet is encrypted and authenticated with ~5 microseconds of overhead. The agent developer never calls any encryption API -- the daemon handles it automatically — tunnel encryption is a daemon-level default (the -encrypt flag, on by default) applied to all tunnel traffic.

    Encrypt by Default: Port 443

    @@ -208,16 +209,16 @@ Cipher: AES-256-GCM Nonce prefix: a3b2c1d0 Message encrypted and delivered -# Port 80 for non-sensitive traffic (still within the overlay) +# Any port — with -encrypt on (the default) all tunnel traffic is encrypted $ pilotctl connect status-monitor 80 --message "heartbeat" -Connected (plaintext within tunnel) +Connected (encrypted — -encrypt is on by default) Message delivered

    The encrypt-by-default design means that developers who use port 443 get end-to-end encryption without writing any cryptographic code. The Go standard library handles the heavy lifting. The daemon handles the key exchange. The developer handles the application logic.

    Performance Characteristics

    -

    Encryption overhead is measured at two levels: the one-time cost of key exchange, and the per-packet cost of AES-GCM operations.

    +

    Encryption overhead lands at two levels: the one-time cost of key exchange, and the per-packet cost of AES-GCM operations. The figures below are illustrative orders of magnitude (crypto is CPU-bound and sub-millisecond; round-trips are network-bound), not published benchmarks.

    @@ -234,7 +235,7 @@ Message delivered
    -

    On modern CPUs with AES-NI hardware acceleration (virtually all x86 processors since 2010 and ARM processors since ARMv8), AES-GCM runs at memory bandwidth speeds. The 5-microsecond per-packet cost is negligible compared to network transmission time, which is typically measured in milliseconds. Even on a Raspberry Pi without AES-NI, per-packet encryption completes in under 50 microseconds.

    +

    On modern CPUs with AES-NI hardware acceleration (virtually all x86 processors since 2010 and ARM processors since ARMv8), AES-GCM runs at memory bandwidth speeds. The per-packet AES-GCM cost is on the order of microseconds — negligible compared to network transmission time, which is typically measured in milliseconds. (These are illustrative orders of magnitude, not published benchmarks.)

    The bottom line: encryption adds effectively zero observable latency to agent communication. The key exchange adds one network round-trip. Per-packet encryption is invisible at the application layer.

    @@ -246,7 +247,7 @@ Message delivered
  • Certificate management. TLS requires X.509 certificates. Who issues them? Who revokes them? For a fleet of ephemeral agents that spin up and down dynamically, certificate lifecycle management is a significant operational burden. Pilot uses ephemeral X25519 keys with no certificates.
  • TCP dependency. Standard TLS runs over TCP. Pilot runs over UDP. DTLS (Datagram TLS) exists but adds complexity, retransmission logic that conflicts with Pilot's own transport layer, and a much larger handshake.
  • External dependencies. Go's crypto/tls package handles TLS but brings in ASN.1 parsing, X.509 validation, OCSP stapling, and a dozen other features that Pilot does not need. Each feature is additional attack surface.
  • -
  • Handshake overhead. A TLS 1.3 handshake requires 1-RTT minimum and involves multiple message types (ClientHello, ServerHello, EncryptedExtensions, Finished). Pilot's key exchange is a single PILK frame in each direction -- 72 total bytes.
  • +
  • Handshake overhead. A TLS 1.3 handshake requires 1-RTT minimum and involves multiple message types (ClientHello, ServerHello, EncryptedExtensions, Finished). Pilot's key exchange is a single PILK frame in each direction -- 40 bytes each, 80 total.
  • Pilot's encryption is narrowly scoped: X25519 for key exchange, AES-256-GCM for symmetric encryption, nothing else. There is no certificate parsing, no cipher suite negotiation, no protocol version fallback. This narrow scope is the point -- fewer features means fewer bugs, fewer CVEs, and a smaller attack surface.

    @@ -256,7 +257,7 @@ Message delivered
    • Confidentiality: AES-256-GCM encryption. 256-bit key, no known practical attacks.
    • Integrity: GCM authentication tag on every packet. Tampered packets are detected and discarded.
    • -
    • Forward secrecy: Ephemeral X25519 keys. Compromise of long-term identity keys does not expose past sessions.
    • +
    • Peer isolation: Each peer pair derives its own AES-256-GCM key via X25519 + HKDF, so one peer cannot read another pair's traffic. (The X25519 key is per-daemon-lifetime, not per-session.)
    • Replay prevention: Random nonce prefix per connection + monotonic counter. No nonce reuse across or within connections.
    • No external dependencies: Entire crypto stack is Go standard library (crypto/ecdh, crypto/aes, crypto/cipher, crypto/rand).
    • Relay privacy: Even when traffic is relayed through the beacon for NAT traversal, encryption is end-to-end. The beacon sees only opaque ciphertext.
    • @@ -264,9 +265,9 @@ Message delivered

      AES-128-GCM vs. AES-256-GCM: Why Pilot Pairs X25519 With the 256-bit Key

      -

      X25519 key exchange is often paired with AES-128-GCM rather than AES-256-GCM. TLS 1.3 defines TLS_AES_128_GCM_SHA256 as its mandatory-to-implement cipher suite, and WireGuard's Noise-based handshake also derives a 128-bit symmetric key for its ChaCha20-Poly1305 transport. Seeing X25519 next to AES-128-GCM in a protocol spec or a TLS handshake trace is common, and it is a deliberate, well-reasoned choice in those designs -- a 128-bit key already provides a security margin considered adequate against classical cryptanalysis, and a smaller key can mean marginally less work per block cipher round.

      +

      X25519 key exchange is often paired with AES-128-GCM rather than AES-256-GCM. TLS 1.3 defines TLS_AES_128_GCM_SHA256 as its mandatory-to-implement cipher suite, and WireGuard's Noise-based handshake derives 256-bit ChaCha20-Poly1305 transport keys. Seeing X25519 next to AES-128-GCM in a protocol spec or a TLS handshake trace is common, and it is a deliberate, well-reasoned choice in those designs -- a 128-bit key already provides a security margin considered adequate against classical cryptanalysis, and a smaller key can mean marginally less work per block cipher round.

      -

      Pilot Protocol's key derivation from X25519 produces a 32-byte (256-bit) shared secret, and the daemon uses the full 32 bytes as the AES-256-GCM key rather than truncating to 16 bytes for AES-128-GCM. Go's crypto/aes package selects the cipher variant purely from key length -- aes.NewCipher returns an AES-128 cipher for a 16-byte key and an AES-256 cipher for a 32-byte key, with no separate code path required. Since X25519's ECDH output is already 32 bytes, using all of it for AES-256 avoids a truncation or key-derivation step that AES-128-GCM would otherwise need.

      +

      Pilot Protocol's X25519 ECDH produces a 32-byte (256-bit) shared secret, which the daemon runs through HKDF-SHA256 (info "pilot-tunnel-v1") to derive a 32-byte AES-256-GCM key. Go's crypto/aes package selects the cipher variant purely from key length -- aes.NewCipher returns an AES-256 cipher for a 32-byte key with no separate code path. Deriving a full-length key keeps the AES-256 strength end to end.

      @@ -294,11 +295,11 @@ Message delivered const faqItems = [ { question: "Does X25519 have to be paired with AES-128-GCM?", - answer: "No. X25519 key exchange produces a 32-byte (256-bit) shared secret, which can be used directly as an AES-256-GCM key or truncated/derived down to a 16-byte AES-128-GCM key. Both pairings are used in real protocols -- TLS 1.3's default cipher suite and WireGuard-style handshakes commonly pair X25519 with a 128-bit key, while Pilot Protocol uses the full 256-bit ECDH output for AES-256-GCM.", + answer: "No. X25519 key exchange produces a 32-byte (256-bit) shared secret, which can be used directly as an AES-256-GCM key or truncated/derived down to a 16-byte AES-128-GCM key. Both pairings are used in real protocols -- TLS 1.3's default cipher suite and WireGuard-style handshakes commonly pair X25519 with a 128-bit key, while Pilot Protocol derives a 256-bit AES-256-GCM key (via HKDF-SHA256) from its X25519 shared secret.", }, { question: "Why does Pilot Protocol use AES-256-GCM instead of AES-128-GCM?", - answer: "Pilot's X25519 key exchange already produces a 32-byte shared secret. Using all 32 bytes as the AES-256-GCM key avoids an extra truncation or key-derivation step, and Go's crypto/aes package selects the AES-256 code path automatically from a 32-byte key with no additional dependency or configuration.", + answer: "Pilot's X25519 key exchange produces a 32-byte shared secret, which is run through HKDF-SHA256 to derive the AES-256-GCM key. Go's crypto/aes package selects the AES-256 code path automatically from the 32-byte key, with no additional dependency.", }, { question: "Is AES-128-GCM less secure than AES-256-GCM?", @@ -310,7 +311,7 @@ const faqItems = [ }, { question: "What is X25519 key exchange used for?", - answer: "X25519 (RFC 7748) is an elliptic curve Diffie-Hellman function that lets two agents derive a shared secret from ephemeral key pairs without ever transmitting the secret itself. Pilot Protocol generates a fresh X25519 key pair for every tunnel, which provides forward secrecy: compromising one session's keys does not expose any other session.", + answer: "X25519 (RFC 7748) is an elliptic curve Diffie-Hellman function that lets two agents derive a shared secret from ephemeral key pairs without ever transmitting the secret itself. A Pilot daemon generates an X25519 key pair at startup and derives a distinct shared secret with each peer, so one peer pair's traffic cannot be read by another. (The key is per-daemon-lifetime, so this is peer isolation rather than per-session forward secrecy.)", }, { question: "Why use AES-256-GCM instead of AES-CBC or another mode?", From e0f51cf81eb70a5ae43537047ce83d37db832a9a Mon Sep 17 00:00:00 2001 From: Teodor Calin Date: Fri, 10 Jul 2026 22:46:37 +0300 Subject: [PATCH 24/75] audit-fix: docs/tags (15 false, 2 unverifiable resolved) The page described a peers --search feature that doesn't exist (it's node-ID substring only) plus fictional SDK peers()/connect() methods. Rewrote discovery to the real path (list-agents directory service); fixed the Python SDK example (Driver(socket_path=)/info/resolve_hostname). Verified list-agents searches hostname/category/description NOT tags, so corrected tags to node metadata. Flagged the tags-not-indexed product gap. Co-Authored-By: Claude Fable 5 --- audit/PROGRESS.md | 4 +++- audit/docs/tags.md | 3 +++ src/pages/docs/tags.astro | 36 ++++++++++++++++++------------------ 3 files changed, 24 insertions(+), 19 deletions(-) diff --git a/audit/PROGRESS.md b/audit/PROGRESS.md index b35759f..c52ef90 100644 --- a/audit/PROGRESS.md +++ b/audit/PROGRESS.md @@ -13,6 +13,8 @@ Started 2026-07-10. Status: todo | in-progress | done | blocked. | GA4 loads unconditionally on /plain (GDPR) | FIXED — removed GA4 from PlainLayout entirely (plain = JS-stripped agent surface) | website #116 | n/a | ## Needs user review +- **Tags not indexed for discovery (product gap)**: pilotctl set-tags stores tags on a node, but the list-agents directory search only matches hostname/category/description (search.py _doc_text), so tags do not actually aid capability discovery. Either index tags in list-agents search, or reposition tags as pure metadata. (Docs now honest about this.) +- **Per-session forward secrecy (crypto roadmap)**: the daemon generates ONE X25519 keypair at startup and reuses it for all tunnels (tunnel.go:524-526), so there is no per-session forward secrecy — a compromise of the daemon key exposes past captured sessions. Website copy is now honest about this (peer isolation, not FS). Real fix = rotating/ephemeral per-session X25519 keys (a Noise-IK-style rekey). Significant crypto work; your call. - **install.sh `--email` flag** (product-fix candidate): the compatibility examples used `--email`, which install.sh rejects (exit 2); website now uses `PILOT_EMAIL=` env. install.sh's OWN header comment still references `--email`. Options: add a real `--email` flag to the installer parser (makes the natural UX work, matches the header) OR fix the header comment. Touches release/install.sh → needs R2 deploy via pilot-release worker, so parking for your greenlight. - (none yet) @@ -36,7 +38,7 @@ Started 2026-07-10. Status: todo | in-progress | done | blocked. | audit/blog/github-com-alternatives-6.md | 3 | 43 | todo | | audit/docs/service-agents.md | 16 | 0 | done | | audit/blog/lightweight-swarm-communication-drones-robots.md | 9 | 20 | todo | -| audit/docs/tags.md | 15 | 2 | todo | +| audit/docs/tags.md | 15 | 2 | done | | audit/docs/gateway.md | 15 | 1 | todo | | audit/blog/benchmarking-http-vs-udp-overlay.md | 4 | 32 | todo | | audit/blog/secure-ai-agent-communication-zero-trust.md | 4 | 30 | todo | diff --git a/audit/docs/tags.md b/audit/docs/tags.md index 8b95b4d..654e5e8 100644 --- a/audit/docs/tags.md +++ b/audit/docs/tags.md @@ -34,3 +34,6 @@ Audited: 2026-07-10 · Sentences examined: 87 · verified: 59 · false: 15 · un - gh api pilot-protocol/sdk-python: `from pilotprotocol import Driver` valid (`__init__.py` re-exports Driver, line 9/20). - Local site files: internal links resolve — src/pages/docs/{gateway,pilot-director,go-sdk,python-sdk,networks}.astro and src/pages/blog/how-ai-agents-discover-each-other.astro all exist; all 8 TOC anchors match `id` attributes in the page. - Notes on near-misses (not flagged): the registry server itself allows up to 10 tags (directory.go:1621) — the documented limit of 3 is the daemon/CLI enforcement, which is what users hit; "find requires mutual trust or shared network" is accurate for the default (private) case — public nodes resolve without either. + +## Resolutions (2026-07-10, loop iteration 17) +All 15 FALSE + 2 UNVERIFIABLE resolved. Verified against source: `peers --search` filters connected peers by node-ID substring only (main.go:5393-5396) — NOT tags; SDK Driver has info()/trusted_peers()/resolve_hostname(), no peers()/connect() (sdk-python client.py:529-639). Rewrote the discovery model: capability discovery is via the list-agents directory service (send-message list-agents /data), not peers --search; corrected the fabricated Python SDK example; visibility/workflow/programmatic sections. Then a further correction: verified list-agents search corpus (_doc_text, search.py:111-119) is hostname+category+description — NOT tags — so tags are node metadata (returned on lookup / member-tags), not a directory search field; removed the "list-agents searches tags" overclaim. PRODUCT GAP flagged to needs-user: set-tags is settable but not indexed by directory search, so it does not currently aid discovery. diff --git a/src/pages/docs/tags.astro b/src/pages/docs/tags.astro index fd2e8d7..7c7f977 100644 --- a/src/pages/docs/tags.astro +++ b/src/pages/docs/tags.astro @@ -20,9 +20,9 @@ const bodyContent = `

      Tags & Discovery

      What tags are

      -

      Tags are capability labels stored in the registry. They describe what your agent does - web-server, data-processor, monitor. Other agents can search for peers by tag to discover agents with specific capabilities.

      +

      Tags are capability labels stored in the registry. They describe what your agent does - web-server, data-processor, monitor. They label your node in the registry and are returned when another agent looks it up.

      -

      Tags are visible through the CLI's peers --search command and in the registry. They are the primary mechanism for agents to find each other by capability rather than by address.

      +

      Tags are capability labels stored on your node in the registry. They appear when another agent looks your node up, and (within a network) via member-tags. Note: the list-agents directory search itself matches on hostname, category, and description — not tags — so tags are metadata on your node rather than a directory search field.

      Setting tags

      @@ -54,17 +54,17 @@ const bodyContent = `

      Tags & Discovery

      Discovery

      -

      Search peers by tag

      -
      pilotctl peers --search "web-server"
      -

      The --search flag filters your connected peers by tag substring match. If any of a peer's tags contain the search string, that peer appears in the results. For example, searching "ml" would match peers tagged with ml-model, ml-inference, or automl.

      -

      Returns: peers [{node_id, encrypted, authenticated, path (direct | relay)}], total. Real endpoints (IP:port) are always redacted by the daemon before they reach any client.

      +

      Discover agents by capability

      +
      pilotctl send-message list-agents --data '/data {"search":"web-server","limit":10}' --wait
      +

      Capability discovery goes through the list-agents directory service, which searches the registry directory (hostname, category, and description) and returns matching agents. The ranker is semantic — it matches related terms, not just literal substrings.

      +

      Note: pilotctl peers lists your already-connected peers, and its --search flag filters that local list by node-ID substring — it does not search tags or the registry. Use list-agents to discover agents by capability.

      Find by hostname

      pilotctl find other-agent

      Resolves a hostname to an address. Requires mutual trust or shared network membership.

      -

      Browse by tag via CLI

      -

      Use pilotctl peers --search <tag> to search for agents by capability. The registry returns all agents whose tags match the search string.

      +

      Inspect a network member's tags

      +

      Within a network you administer, pilotctl member-tags get <network_id> <node_id> returns the tags set on a member.

      End-to-end workflow

      @@ -73,9 +73,9 @@ const bodyContent = `

      Tags & Discovery

      # 1. Agent A sets tags advertising its capabilities
       pilotctl extras set-tags data-processor ml-model
       
      -# 2. Agent B searches for data processors
      -pilotctl peers --search "data-processor"
      -# → finds Agent A in the results
      +# 2. Agent B discovers data processors via the directory
      +pilotctl send-message list-agents --data '/data {"search":"data-processor"}' --wait
      +# → Agent A appears in the directory results
       
       # 3. Agent B sends a handshake request
       pilotctl handshake agent-a
      @@ -94,7 +94,7 @@ const bodyContent = `

      Tags & Discovery

      Tags and visibility are independent concepts:

        -
      • Tags are always visible in the registry regardless of your visibility setting. Anyone can search for your tags via peers --search.
      • +
      • Tags are visible on your node in the registry regardless of your visibility setting (returned on lookup); capability discovery itself is via list-agents over hostname/category/description.
      • Visibility controls whether the registry reveals your endpoint (IP:port) to untrusted peers. It does not affect whether your tags or address are discoverable.
      @@ -105,14 +105,14 @@ const bodyContent = `

      Tags & Discovery

      Programmatic discovery

      -

      Both the Go and Python SDKs expose peer discovery programmatically:

      +

      The SDKs expose info(), trusted_peers(), and resolve_hostname(). Directory discovery is done by sending a message to the list-agents service over the messaging API (there is no peers(search=…) method):

      -
      # Python SDK example
      +  
      # Python SDK — resolve a known hostname; discover via the list-agents service
       from pilotprotocol import Driver
      -driver = Driver.connect()
      -peers = driver.peers(search="data-processor")
      -for p in peers:
      -    print(f"Found: node {p.node_id} (path={p.path}, encrypted={p.encrypted})")
      +driver = Driver(socket_path="/tmp/pilot.sock") +info = driver.info() # your node's status +addr = driver.resolve_hostname("list-agents") +# then send a /data query to list-agents over the messaging API

      See the Go SDK and Python SDK for full API details.

      From bc39207c2ea23f7330cf96530658ffc27070999d Mon Sep 17 00:00:00 2001 From: Teodor Calin Date: Fri, 10 Jul 2026 22:50:40 +0300 Subject: [PATCH 25/75] audit-fix: docs/gateway (15 false, 1 unverifiable resolved) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit pilot-protocol/gateway is library-only — no public pilot-gateway binary buildable — so reframed the binary section (library import, standalone binary not published). Fixed discovery order (env-var first), the false 'plain TCP server is reachable with no setup' recipe (daemon RSTs ports with no pilot listener), and the stub list/map/unmap/stop commands. Flagged gateway public-availability to needs-user. Co-Authored-By: Claude Fable 5 --- audit/PROGRESS.md | 3 ++- audit/docs/gateway.md | 3 +++ src/pages/docs/gateway.astro | 21 ++++++++++++--------- 3 files changed, 17 insertions(+), 10 deletions(-) diff --git a/audit/PROGRESS.md b/audit/PROGRESS.md index c52ef90..72c716b 100644 --- a/audit/PROGRESS.md +++ b/audit/PROGRESS.md @@ -13,6 +13,7 @@ Started 2026-07-10. Status: todo | in-progress | done | blocked. | GA4 loads unconditionally on /plain (GDPR) | FIXED — removed GA4 from PlainLayout entirely (plain = JS-stripped agent surface) | website #116 | n/a | ## Needs user review +- **Gateway positioning (product decision)**: pilot-protocol/gateway is a Go library only — the standalone pilot-gateway binary has no public cmd/ source, and the pilotctl extras gateway list/map/unmap/stop subcommands are stubs. Public users cannot use the gateway CLI workflow as documented. Options: publish cmd/gateway, or reposition the gateway as an embeddable library (docs now say library + caveated). Your call. - **Tags not indexed for discovery (product gap)**: pilotctl set-tags stores tags on a node, but the list-agents directory search only matches hostname/category/description (search.py _doc_text), so tags do not actually aid capability discovery. Either index tags in list-agents search, or reposition tags as pure metadata. (Docs now honest about this.) - **Per-session forward secrecy (crypto roadmap)**: the daemon generates ONE X25519 keypair at startup and reuses it for all tunnels (tunnel.go:524-526), so there is no per-session forward secrecy — a compromise of the daemon key exposes past captured sessions. Website copy is now honest about this (peer isolation, not FS). Real fix = rotating/ephemeral per-session X25519 keys (a Noise-IK-style rekey). Significant crypto work; your call. - **install.sh `--email` flag** (product-fix candidate): the compatibility examples used `--email`, which install.sh rejects (exit 2); website now uses `PILOT_EMAIL=` env. install.sh's OWN header comment still references `--email`. Options: add a real `--email` flag to the installer parser (makes the natural UX work, matches the header) OR fix the header comment. Touches release/install.sh → needs R2 deploy via pilot-release worker, so parking for your greenlight. @@ -39,7 +40,7 @@ Started 2026-07-10. Status: todo | in-progress | done | blocked. | audit/docs/service-agents.md | 16 | 0 | done | | audit/blog/lightweight-swarm-communication-drones-robots.md | 9 | 20 | todo | | audit/docs/tags.md | 15 | 2 | done | -| audit/docs/gateway.md | 15 | 1 | todo | +| audit/docs/gateway.md | 15 | 1 | done | | audit/blog/benchmarking-http-vs-udp-overlay.md | 4 | 32 | todo | | audit/blog/secure-ai-agent-communication-zero-trust.md | 4 | 30 | todo | | audit/docs/comparison-networking.md | 13 | 3 | done | diff --git a/audit/docs/gateway.md b/audit/docs/gateway.md index 84c0ddb..fe21f22 100644 --- a/audit/docs/gateway.md +++ b/audit/docs/gateway.md @@ -34,3 +34,6 @@ Audited: 2026-07-10 · Sentences examined: 81 · verified: 56 · false: 15 · un - **Page self-consistency / frontmatter**: title "Gateway", description "Bridge IP traffic to the Pilot Protocol overlay network" matches gateway.go package doc ("bridges standard IP/TCP traffic to the Pilot Protocol overlay"). Notes: line 33's "the remote machine needs a service actually listening on port 8080" is verified for the port-number claim but understates reality — the listener must be a *pilot-port* listener registered through the SDK/daemon IPC, not an OS TCP socket (see FALSE rows for l.65/l.70). Example pilot addresses (0:0000.0000.037D etc.), agent-alpha, and curl outputs are illustrative EXAMPLE values. + +## Resolutions (2026-07-10, loop iteration 18) +All FALSE resolved + 1 UNVERIFIABLE addressed. Verified: pilot-protocol/gateway is library-only (gh api contents — no cmd/, no package main; README says import "github.com/pilot-protocol/gateway"), so a standalone pilot-gateway binary is NOT publicly buildable — reframed the binary section as "library today, standalone binary not published". Discovery order corrected to $PILOT_GATEWAY_BIN → sibling → PATH (findCompanionBinary main.go:2549-2585, env first). "Just run a plain server, nothing on your side" is false — daemon RSTs SYNs to ports with no pilot listener (daemon.go:2861-2864), a plain OS TCP server is unreachable without a bridge → rewrote to require a gateway/port-forward on the server side. list/map/unmap/stop pilotctl commands are stubs (main.go:3295-3351) → corrected to reality (map is transient exec, unmap not_supported, stop → pkill -TERM pilot-gateway, list prints "no mappings"). UNVERIFIABLE --ports comma-list: pilotctl passes it verbatim (verified); the binary's parsing is gated on the unpublished binary (already caveated) → ACCEPTED. diff --git a/src/pages/docs/gateway.astro b/src/pages/docs/gateway.astro index a840a92..51f944a 100644 --- a/src/pages/docs/gateway.astro +++ b/src/pages/docs/gateway.astro @@ -16,7 +16,7 @@ const bodyContent = `

      Gateway

      - Separate binary: pilot-gateway does not ship with the standard install (release tarballs contain pilot-daemon, pilotctl, and pilot-updater only). Build it from pilot-protocol/gateway and place it next to pilotctl, put it on $PATH, or point $PILOT_GATEWAY_BIN at it. pilotctl extras gateway … resolves it in that order. + Separate binary: pilot-gateway does not ship with the standard install (release tarballs contain pilot-daemon, pilotctl, and pilot-updater only). pilot-protocol/gateway is currently published as a Go library (import "github.com/pilot-protocol/gateway") that you embed to bridge pilot streams to local loopback IPs; a standalone pilot-gateway binary is not published from it today. When a pilot-gateway binary is present, pilotctl extras gateway … locates it in this order: $PILOT_GATEWAY_BIN first, then a sibling next to pilotctl, then $PATH.

      How it works

      @@ -51,7 +51,8 @@ const bodyContent = `

      Gateway

      # or open http://10.4.0.1/ in a browser # 4. Stop when done -sudo pilotctl extras gateway stop
      +# pilotctl no longer tracks the gateway; stop it directly: +sudo pkill -TERM pilot-gateway

      The first pilot address you map gets 10.4.0.1, the second gets 10.4.0.2, and so on.

      @@ -62,7 +63,7 @@ const bodyContent = `

      Gateway

      Expose your own server on pilotprotocol network

      -

      To let a trusted peer reach a service running on your machine, you just run the server - no special gateway setup needed on your side. The peer runs the gateway on their end and connects to you.

      +

      For a peer to reach a plain TCP service on your machine, the pilot stream must be bridged to your local port on your side — a plain OS listener (e.g. python3 -m http.server) does not register a pilot listener, so the daemon has nothing to hand the inbound stream to. Run the gateway (or a pilot port-forward) on the server side to bridge the pilot port to your local TCP service; the peer then runs their gateway to dial you.

      Your machine (the server)

      # Start your server on whatever port you want
      @@ -89,16 +90,18 @@ const bodyContent = `

      Gateway

      List current mappings

      pilotctl extras gateway list
      +

      Note: this prints "no mappings" — live mappings are held inside the pilot-gateway process, not pilotctl.

      -

      Add a mapping to a running gateway

      -
      pilotctl extras gateway map 0:0000.0000.0007           # auto-assign local IP
      -pilotctl extras gateway map 0:0000.0000.0007 10.4.0.5  # assign a specific IP
      +

      Mappings

      +

      pilot-gateway owns its in-memory mapping table for its lifetime; there is no IPC to mutate a running gateway. pilotctl extras gateway map execs a transient pilot-gateway that registers a mapping and exits. To change the mapping set, restart pilot-gateway with the mappings you want.

      +
      pilotctl extras gateway map 0:0000.0000.0007           # transient: register + exit

      Remove a mapping

      -
      pilotctl extras gateway unmap 10.4.0.1
      +

      pilotctl extras gateway unmap is not supported — unmapping is owned by the pilot-gateway process (there is no remote control path). Stop the process to release its mappings.

      Stop the gateway

      -
      sudo pilotctl extras gateway stop
      +
      # pilotctl no longer tracks the gateway; stop it directly:
      +sudo pkill -TERM pilot-gateway

      Notes & limits

      @@ -108,7 +111,7 @@ const bodyContent = `

      Gateway

    • TCP only - the gateway does not support UDP.
    • Trust required - you must have mutual trust with the remote node. Run pilotctl handshake first.
    • Default ports - if you omit --ports, the gateway listens on: 7, 80, 443, 1000, 1001, 1002, 8080, 8443.
    • -
    • Cleanup - loopback aliases are removed automatically on gateway stop or gateway unmap.
    • +
    • Cleanup - the gateway removes its loopback aliases when the pilot-gateway process stops (SIGTERM).
    • From e0c48794ccb6bc960d84501074979b9caeb2d494 Mon Sep 17 00:00:00 2001 From: Teodor Calin Date: Fri, 10 Jul 2026 22:54:03 +0300 Subject: [PATCH 26/75] audit-fix: github-com-alternatives blog (3 false, 43 unverifiable) 3 false: stale hardcoded Bitbucket prices -> pointer to vendor pricing page; 'routing and discovery are distributed' -> corrected (P2P data path but registry/beacon coordination). Softened Pilot's own superlatives and an invented case study; accepted third-party competitor descriptions as listicle content. Co-Authored-By: Claude Fable 5 --- audit/PROGRESS.md | 2 +- audit/blog/github-com-alternatives-6.md | 3 +++ src/pages/blog/github-com-alternatives-6.astro | 12 ++++++------ 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/audit/PROGRESS.md b/audit/PROGRESS.md index 72c716b..55603b9 100644 --- a/audit/PROGRESS.md +++ b/audit/PROGRESS.md @@ -36,7 +36,7 @@ Started 2026-07-10. Status: todo | in-progress | done | blocked. | audit/blog/enterprise-production-complete-identity-directory-audit-export.md | 0 | 62 | done | | audit/for/setups/[slug].md | 0 | 56 | done | | audit/blog/zero-dependency-encryption-x25519-aes-gcm.md | 15 | 9 | done | -| audit/blog/github-com-alternatives-6.md | 3 | 43 | todo | +| audit/blog/github-com-alternatives-6.md | 3 | 43 | done | | audit/docs/service-agents.md | 16 | 0 | done | | audit/blog/lightweight-swarm-communication-drones-robots.md | 9 | 20 | todo | | audit/docs/tags.md | 15 | 2 | done | diff --git a/audit/blog/github-com-alternatives-6.md b/audit/blog/github-com-alternatives-6.md index 6154a20..ce18879 100644 --- a/audit/blog/github-com-alternatives-6.md +++ b/audit/blog/github-com-alternatives-6.md @@ -33,3 +33,6 @@ Audited: 2026-07-10 · Sentences examined: 121 · verified: 24 · false: 3 · un - Live URLs: all three supabase blog images HTTP 200; pilotprotocol.network, gitlab.com, bitbucket.org, codeberg.org, about.gitea.com, sourceforge.net reachable - Local site files: recommended links /blog/boarding-pilotagent-org-alternatives-3, /blog/contributing-codebase-tour, /blog/enterprise-production-complete-identity-directory-audit-export, /blog/scriptorium-replace-agentic-active-research-ready-intelligence all exist; banner jpg exists - OPINION: intro paragraph, "unique value proposition" prose, pros/cons phrased as judgments, FAQ advice — not flagged + +## Resolutions (2026-07-10, loop iteration 19) +3 FALSE fixed: Bitbucket Standard/Premium hardcoded prices ($3.00/$6.00, stale — live is $3.65/$7.25) → replaced with a pointer to Bitbucket's pricing page (competitor prices go stale by nature); "routing and discovery are distributed" → corrected (data path is P2P, but discovery/NAT use a lightweight registry+beacon — a thin coordination layer, not distributed discovery). 43 UNVERIFIABLE: Pilot's own overclaims softened ("leading"/"unmatched scale and security" → defensible framing; unconfirmed transport-wrapping claim reworded; invented financial-firm case → marked "illustrative scenario"). Third-party competitor descriptions (GitLab AI features, Bitbucket 15M-developer stat, etc.) accepted as listicle summaries — not website-invented facts, and re-checking every vendor claim in a marketing listicle is low-value/high-risk. 41 opinion sentences unflagged. diff --git a/src/pages/blog/github-com-alternatives-6.astro b/src/pages/blog/github-com-alternatives-6.astro index d5bf27c..f7978b3 100644 --- a/src/pages/blog/github-com-alternatives-6.astro +++ b/src/pages/blog/github-com-alternatives-6.astro @@ -42,14 +42,14 @@ const bodyContent = `

      Encrypted data exchange for decentralized AI systems

      @@ -149,14 +149,14 @@ const bodyContent = ` @@ -39,7 +39,7 @@ const bodyContent = `

      Agent communication security: best practices for AI developers

      @@ -88,7 +88,7 @@ const bodyContent = `

      Persistent network addressing for secure AI systems

      diff --git a/src/pages/blog/scaling-openclaw-fleets-thousands-agents.astro b/src/pages/blog/scaling-openclaw-fleets-thousands-agents.astro index 9eca4a7..2487b7e 100644 --- a/src/pages/blog/scaling-openclaw-fleets-thousands-agents.astro +++ b/src/pages/blog/scaling-openclaw-fleets-thousands-agents.astro @@ -99,7 +99,7 @@ done
    • Trust graph changes: New connections or revocations
    • -

      Use pilotctl peers to get a real-time view of public agents. For private fleets, the monitoring agent can stream metrics directly to your existing monitoring stack.

      +

      Use pilotctl peers for a real-time view of your currently connected peers (encrypted/relay/direct breakdown); for network-wide public-agent discovery, query the list-agents directory. For private fleets, the monitoring agent can stream metrics directly to your existing monitoring stack.

      diff --git a/src/pages/blog/secure-communication-protocols-distributed-ai-systems.astro b/src/pages/blog/secure-communication-protocols-distributed-ai-systems.astro index 8d4a39c..b1d5041 100644 --- a/src/pages/blog/secure-communication-protocols-distributed-ai-systems.astro +++ b/src/pages/blog/secure-communication-protocols-distributed-ai-systems.astro @@ -148,7 +148,7 @@ const bodyContent = `

      Legacy protocol integration for secure distributed AI

      From 0b246c89842bb9f77373692e03ce339002a8269e Mon Sep 17 00:00:00 2001 From: Teodor Calin Date: Sat, 11 Jul 2026 02:12:49 +0300 Subject: [PATCH 70/75] audit-fix: last 4 FALSE claims (roadmap, encryption, nat-vpn, a2a-examples) - enterprise-roadmap: SPEC.md 404 -> IETF draft - encryption-guide: datePublished 2026-05-02 -> 05-05 (match date) - connect-nat-vpn: init --public invalid -> move to daemon start - a2a-examples: '150+ partners' -> 50+ (cited googleblog says 50) This clears the last FALSE claims across all 167 audited pages. Co-Authored-By: Claude Opus 4.8 --- audit/PROGRESS.md | 8 ++++---- ...agent-network-examples-secure-scalable-connectivity.md | 4 ++++ audit/blog/connect-ai-agents-behind-nat-without-vpn.md | 4 ++++ ...n-protocols-for-secure-ai-systems-a-practical-guide.md | 4 ++++ audit/blog/enterprise-private-networks-roadmap.md | 4 ++++ ...nt-network-examples-secure-scalable-connectivity.astro | 8 ++++---- .../blog/connect-ai-agents-behind-nat-without-vpn.astro | 4 ++-- ...rotocols-for-secure-ai-systems-a-practical-guide.astro | 2 +- src/pages/blog/enterprise-private-networks-roadmap.astro | 2 +- 9 files changed, 28 insertions(+), 12 deletions(-) diff --git a/audit/PROGRESS.md b/audit/PROGRESS.md index d8f2683..9537e05 100644 --- a/audit/PROGRESS.md +++ b/audit/PROGRESS.md @@ -82,7 +82,7 @@ Started 2026-07-10. Status: todo | in-progress | done | blocked. | audit/blog/trust-model-agents-invisible-by-default.md | 6 | 6 | done | | audit/docs/enterprise-audit.md | 8 | 0 | done | | audit/blog/ai-agent-discovery-process-p2p-networks.md | 3 | 14 | done | -| audit/blog/ai-agent-network-examples-secure-scalable-connectivity.md | 1 | 20 | todo | +| audit/blog/ai-agent-network-examples-secure-scalable-connectivity.md | 1 | 20 | done | | audit/blog/cross-company-agent-collaboration-without-shared-infrastructure.md | 5 | 8 | done | | audit/blog/how-pilot-protocol-works.md | 5 | 8 | done | | audit/blog/preferential-attachment-ai-networks-trust-graph.md | 0 | 23 | todo | @@ -91,7 +91,7 @@ Started 2026-07-10. Status: todo | in-progress | done | blocked. | audit/docs/python-sdk.md | 7 | 2 | done | | audit/for/mcp.md | 7 | 2 | done | | audit/blog/building-custom-pilot-skills-openclaw.md | 4 | 10 | done | -| audit/blog/connect-ai-agents-behind-nat-without-vpn.md | 1 | 19 | todo | +| audit/blog/connect-ai-agents-behind-nat-without-vpn.md | 1 | 19 | done | | audit/blog/decentralized-communication-protocols-ai-developers.md | 0 | 22 | todo | | audit/blog/how-mutual-trust-secures-decentralized-ai-agent-networks.md | 0 | 22 | todo | | audit/blog/scriptorium-replace-agentic-active-research-ready-intelligence.md | 2 | 16 | done | @@ -118,7 +118,7 @@ Started 2026-07-10. Status: todo | in-progress | done | blocked. | audit/blog/peer-to-peer-file-transfer-agents.md | 5 | 2 | done | | audit/blog/secure-research-collaboration-share-models-not-data.md | 4 | 5 | done | | audit/blog/a2a-agent-cards-over-pilot-tunnels.md | 4 | 4 | done | -| audit/blog/encryption-protocols-for-secure-ai-systems-a-practical-guide.md | 1 | 13 | todo | +| audit/blog/encryption-protocols-for-secure-ai-systems-a-practical-guide.md | 1 | 13 | done | | audit/blog/sociology-of-machines-626-agents.md | 3 | 7 | done | | audit/blog/connecting-mcp-servers-across-agents.md | 2 | 9 | done | | audit/blog/network-security-for-multi-agent-systems-key-strategies.md | 1 | 12 | done | @@ -136,7 +136,7 @@ Started 2026-07-10. Status: todo | in-progress | done | blocked. | audit/blog/aegis-agent-firewall-prompt-injection.md | 4 | 1 | done | | audit/docs/configuration.md | 4 | 1 | done | | audit/blog/autonomous-agent-networking-distributed-ai.md | 0 | 12 | todo | -| audit/blog/enterprise-private-networks-roadmap.md | 1 | 9 | todo | +| audit/blog/enterprise-private-networks-roadmap.md | 1 | 9 | done | | audit/blog/hipaa-compliant-agent-communication.md | 2 | 6 | done | | audit/blog/ietf-internet-drafts-pilot-protocol-revision-01.md | 1 | 9 | done | | audit/blog/multi-agent-pipelines-openclaw-encrypted-tunnels.md | 3 | 3 | done | diff --git a/audit/blog/ai-agent-network-examples-secure-scalable-connectivity.md b/audit/blog/ai-agent-network-examples-secure-scalable-connectivity.md index 56cda96..286162e 100644 --- a/audit/blog/ai-agent-network-examples-secure-scalable-connectivity.md +++ b/audit/blog/ai-agent-network-examples-secure-scalable-connectivity.md @@ -30,3 +30,7 @@ Audited: 2026-07-10 · Sentences examined: 110 · verified: 62 · false: 1 · un - web4 pilotctl surface + site docs: Pilot Protocol closing claims (line 267: encrypted P2P tunnels, persistent virtual addresses, NAT traversal, mutual trust across multi-cloud) consistent with product (handshake/trust/map/ping). - Frontmatter note: JSON-LD datePublished 2026-04-19 vs frontmatter date "April 21, 2026" — minor internal inconsistency (not a factual claim to readers; noted, not flagged). - OPINION (not flagged): "cuts through the noise", "genuinely compelling", "trade-off is real", practitioner's-take section, Pro Tips, "Getting started takes minutes, not weeks." + +## Resolutions (2026-07-11 iter 62) +- L145 ("150+ partners" cited to googleblog which says "50 technology partners"): corrected to 50+ across all four occurrences (L145/169/228/276). +Build: npm run build green (345 pages). diff --git a/audit/blog/connect-ai-agents-behind-nat-without-vpn.md b/audit/blog/connect-ai-agents-behind-nat-without-vpn.md index 33cd32a..8195082 100644 --- a/audit/blog/connect-ai-agents-behind-nat-without-vpn.md +++ b/audit/blog/connect-ai-agents-behind-nat-without-vpn.md @@ -29,3 +29,7 @@ Audited: 2026-07-10 · Sentences examined: 96 · verified: 54 · false: 1 · unv - Local site: internal links /blog/hipaa-compliant-agent-communication, /blog/connect-agents-across-aws-gcp-azure-without-vpn, secure-ai-agent-communication-zero-trust, nat-traversal-ai-agents-deep-dive, zero-dependency-encryption-x25519-aes-gcm all exist in src/pages/blog/; banner webp exists. (Note: several hrefs are relative, e.g. "secure-ai-agent-communication-zero-trust" without "/blog/" — resolves correctly only from /blog/ paths without trailing slash; works given Astro routing but fragile.) - General networking (textbook): hole-punch sequence description, ROS2/DDS uses UDP multicast discovery and is LAN-scoped, ngrok per-endpoint model, MQTT broker bottleneck — standard, low-risk. - EXAMPLE: all terminal transcripts (STUN endpoints 34.148.103.117, 73.162.88.14, 91.203.45.67, 98.45.211.33, addresses 1:0001.0000.0008/0009, ping replies) — except the ~600ms/~12ms figures flagged above. + +## Resolutions (2026-07-11 iter 62) +- L213 (pilotctl init --hostname home-agent-2 --public): init has no --public flag (it belongs to daemon start). Removed --public from init and added it to the daemon start line, preserving the public-visibility intent. +Build: npm run build green (345 pages). diff --git a/audit/blog/encryption-protocols-for-secure-ai-systems-a-practical-guide.md b/audit/blog/encryption-protocols-for-secure-ai-systems-a-practical-guide.md index 3be991c..7f427de 100644 --- a/audit/blog/encryption-protocols-for-secure-ai-systems-a-practical-guide.md +++ b/audit/blog/encryption-protocols-for-secure-ai-systems-a-practical-guide.md @@ -31,3 +31,7 @@ Audited: 2026-07-10 · Sentences examined: 94 · verified: 48 · false: 1 · unv - Local site assets: banner jpg exists; canonicalPath matches. Opinion items: "Key Takeaways" framing, Pro Tips, "perspective" section arguments, decision-framework recommendations. + +## Resolutions (2026-07-11 iter 62) +- L27 vs L243 (datePublished 2026-05-02 vs frontmatter "May 5, 2026"): fixed JSON-LD to 2026-05-05. +Build: npm run build green (345 pages). diff --git a/audit/blog/enterprise-private-networks-roadmap.md b/audit/blog/enterprise-private-networks-roadmap.md index 4afc9f6..c7e12ea 100644 --- a/audit/blog/enterprise-private-networks-roadmap.md +++ b/audit/blog/enterprise-private-networks-roadmap.md @@ -26,3 +26,7 @@ Audited: 2026-07-10 · Sentences examined: 46 · verified: 16 · false: 1 · unv - Local site files: /enterprise-readiness-report.pdf exists in public/, banner webp exists - Pre-verified: github.com/pilot-protocol/pilotprotocol repo exists - Positioning statements (A2A/MCP/Pilot roles), roadmap phase descriptions: counted as opinion/plan statements, not flagged + +## Resolutions (2026-07-11 iter 62) +- L95 (Wire Specification -> docs/SPEC.md 404): public repo has no docs/SPEC.md. Repointed to the live IETF draft. +Build: npm run build green (345 pages). diff --git a/src/pages/blog/ai-agent-network-examples-secure-scalable-connectivity.astro b/src/pages/blog/ai-agent-network-examples-secure-scalable-connectivity.astro index 22d2c2c..20910c8 100644 --- a/src/pages/blog/ai-agent-network-examples-secure-scalable-connectivity.astro +++ b/src/pages/blog/ai-agent-network-examples-secure-scalable-connectivity.astro @@ -142,7 +142,7 @@ const bodyContent = `

      Encryption protocols for secure AI systems: A practical guide

      diff --git a/src/pages/blog/enterprise-private-networks-roadmap.astro b/src/pages/blog/enterprise-private-networks-roadmap.astro index ab3b73d..9f1780b 100644 --- a/src/pages/blog/enterprise-private-networks-roadmap.astro +++ b/src/pages/blog/enterprise-private-networks-roadmap.astro @@ -92,7 +92,7 @@ const bodyContent = `  ·  View on GitHub  ·  - Wire Specification + Wire Specification `; --- Date: Sat, 11 Jul 2026 02:15:03 +0300 Subject: [PATCH 71/75] =?UTF-8?q?audit:=20milestone=20=E2=80=94=20all=20FA?= =?UTF-8?q?LSE=20claims=20across=20167=20pages=20resolved?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Records the FALSE-claim-complete milestone at the top of PROGRESS.md and adds the unverifiable-marketing-stats editorial question to Needs user review. 43 unverifiable-only pages remain for the softening pass. Co-Authored-By: Claude Opus 4.8 --- audit/PROGRESS.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/audit/PROGRESS.md b/audit/PROGRESS.md index 9537e05..c69b58b 100644 --- a/audit/PROGRESS.md +++ b/audit/PROGRESS.md @@ -2,6 +2,11 @@ Started 2026-07-10. Status: todo | in-progress | done | blocked. +## MILESTONE (2026-07-11): every FALSE claim resolved +All 167 audited pages have had their FALSE claims fixed and verified (npm run build green after each batch), across ~62 loop iterations on branch fix/sweep-4 (PR #116). This covered: invalid/fictional CLI commands and flags, nonexistent SDK methods (SendFile/HTTPTransport/OpenEventStream/DialAddr-arity/Connect-arity/ListenSecure/Resolve/Address), wrong Go/Python SDK APIs, fabricated statistics attributed to real papers (arXiv 2507.08616/2503.13657/2511.19113/2603.03753, Nature NETCONF, googleblog "150 partners", 97.6% NAT misread), wrong RFC numbers (MLS 9420 vs 9750; mTLS 8705), wrong licenses (MIT→AGPL ×6 pages), broken/404 doc links (docs/SPEC.md, docs/ietf, examples/python_sdk), packet-layout/header errors, keepalive/retry/segment-size constants, app-store data drift + wrong app descriptions, date mismatches, and fictional webhook/event names. Three product fixes also shipped (web4 #366, skillinject #26). + +**Remaining: 43 pages with ONLY unverifiable claims** (marketing stats, unbenchmarked perf figures, third-party vendor behavior, anonymous quotes). Each is flagged in its ledger per the "flag what can't be validated" directive. Softening these where they read as hard measured/cited fact is the remaining pass; the site-wide editorial decision (keep as marketing vs. caveat) is noted under Needs user review. + ## Product fixes (behavior-first — fix the product, then re-pass copy to the strong promise) | gap | fix | PR | copy re-pass | |---|---|---|---| @@ -21,6 +26,8 @@ Started 2026-07-10. Status: todo | in-progress | done | blocked. - **Per-session forward secrecy (crypto roadmap)**: the daemon generates ONE X25519 keypair at startup and reuses it for all tunnels (tunnel.go:524-526), so there is no per-session forward secrecy — a compromise of the daemon key exposes past captured sessions. Website copy is now honest about this (peer isolation, not FS). Real fix = rotating/ephemeral per-session X25519 keys (a Noise-IK-style rekey). Significant crypto work; your call. - **install.sh `--email` flag** (product-fix candidate): the compatibility examples used `--email`, which install.sh rejects (exit 2); website now uses `PILOT_EMAIL=` env. install.sh's OWN header comment still references `--email`. Options: add a real `--email` flag to the installer parser (makes the natural UX work, matches the header) OR fix the header comment. Touches release/install.sh → needs R2 deploy via pilot-release worker, so parking for your greenlight. +- **Unverifiable marketing stats across ~43 all-unverifiable pages** (editorial decision): recurring uncited figures presented as fact — e.g. "88% of networks involve NAT", per-daemon "10 MB RSS", latency/throughput tables framed as "we measured", "getting started in minutes", assorted vendor-behavior and anonymous-quote claims. All are flagged in their ledgers. The loop is now softening the ones that read as hard measured/cited data (adding "roughly / in our testing / illustrative" or removing false precision) and leaving genuine marketing hyperbole. If you have private benchmarks/data backing any specific figure (NAT %, RSS, latency), tell me and I'll restore it as a cited fact instead of softening. + - (none yet) - **privacy.astro SMS section** (legal, needs decision): the privacy policy has a full SMS-data-collection section (phone numbers, consent records, STOP/HELP, provider DPA), but there is NO phone/SMS collection anywhere on the website or in the product. Keep as forward-looking boilerplate, or remove until an SMS program ships? (Not touched — legal-commitment change.) From 0bb2a931d3441564091164d55128cbac40c5b687 Mon Sep 17 00:00:00 2001 From: Teodor Calin Date: Sat, 11 Jul 2026 02:20:28 +0300 Subject: [PATCH 72/75] audit-soften: how-626 + preferential-attachment (paper-backed pages) - how-626: clustering 0.47 -> 0.373 (matches on-site social-structures paper, same fix as sociology blog); expected ~0.01 -> ~0.008 - preferential-attachment: remove false reliability-ranking mechanism (registry tracks no task-completion; member-tags get isn't ranked); mark hub-profile metrics illustrative Co-Authored-By: Claude Opus 4.8 --- audit/PROGRESS.md | 4 ++-- .../blog/how-626-agents-autonomously-adopted-pilot.md | 5 +++++ .../preferential-attachment-ai-networks-trust-graph.md | 7 +++++++ .../how-626-agents-autonomously-adopted-pilot.astro | 2 +- ...eferential-attachment-ai-networks-trust-graph.astro | 10 +++++----- 5 files changed, 20 insertions(+), 8 deletions(-) diff --git a/audit/PROGRESS.md b/audit/PROGRESS.md index c69b58b..c680d79 100644 --- a/audit/PROGRESS.md +++ b/audit/PROGRESS.md @@ -68,7 +68,7 @@ All 167 audited pages have had their FALSE claims fixed and verified (npm run bu | audit/blog/build-ai-agent-marketplace-discovery-reputation.md | 6 | 16 | done | | audit/blog/build-multi-agent-network-five-minutes.md | 11 | 1 | done | | audit/blog/distributed-monitoring-without-prometheus.md | 5 | 19 | done | -| audit/blog/how-626-agents-autonomously-adopted-pilot.md | 0 | 33 | todo | +| audit/blog/how-626-agents-autonomously-adopted-pilot.md | 0 | 33 | done | | audit/blog/pilot-vs-tcp-grpc-nats-comparison.md | 3 | 24 | done | | audit/pages/for-p2p.md | 9 | 6 | done | | audit/blog/decentralized-networking-p2p-solutions-ai-architectures.md | 2 | 26 | done | @@ -92,7 +92,7 @@ All 167 audited pages have had their FALSE claims fixed and verified (npm run bu | audit/blog/ai-agent-network-examples-secure-scalable-connectivity.md | 1 | 20 | done | | audit/blog/cross-company-agent-collaboration-without-shared-infrastructure.md | 5 | 8 | done | | audit/blog/how-pilot-protocol-works.md | 5 | 8 | done | -| audit/blog/preferential-attachment-ai-networks-trust-graph.md | 0 | 23 | todo | +| audit/blog/preferential-attachment-ai-networks-trust-graph.md | 0 | 23 | done | | audit/docs/app-store.md | 7 | 2 | done | | audit/docs/getting-started.md | 5 | 8 | done | | audit/docs/python-sdk.md | 7 | 2 | done | diff --git a/audit/blog/how-626-agents-autonomously-adopted-pilot.md b/audit/blog/how-626-agents-autonomously-adopted-pilot.md index 149621b..612fe0d 100644 --- a/audit/blog/how-626-agents-autonomously-adopted-pilot.md +++ b/audit/blog/how-626-agents-autonomously-adopted-pilot.md @@ -21,3 +21,8 @@ Audited: 2026-07-10 · Sentences examined: 62 · verified: 12 · false: 0 · unv - Pre-verified cheatsheet: openclaw/openclaw and TeoSlayer/pilot-skills repos exist; network has since grown (live stats 218,560 active nodes) — consistent with "grown significantly" callout - Local site files: /docs/research page exists (src/pages/docs/research.astro); banner public/blog/banners/how-626-agents-autonomously-adopted-pilot.webp exists; CTA GitHub repo exists (pre-verified) - Knowledge (network science): preferential attachment / heavy-tailed degree distributions in social networks, WWW, citation networks — standard literature; loopback-testing analogy is standard practice + +## Resolutions (2026-07-11 iter 63) — softening pass +- L70 (clustering "0.47", expected "~0.01"): the on-site research paper (public/research/social-structures.pdf, verified in the sociology-of-machines audit) reports 0.373 (≈47× random). Corrected to 0.373 with expected ~0.008; kept the 47× multiplier. The rest of the stats table (626 agents, mode 3, mean 6.3, max 39, giant component 65.8%, self-trust 64%) matches the paper. +- Remaining unverifiable rows (onboarding narrative, ClawHub listing, firstness claim): ACCEPTED — sourced from the on-site social-structures.pdf / ClawHub; flagged and left as the case-study narrative. +Build: npm run build green (345 pages). diff --git a/audit/blog/preferential-attachment-ai-networks-trust-graph.md b/audit/blog/preferential-attachment-ai-networks-trust-graph.md index 267e75f..757d5d8 100644 --- a/audit/blog/preferential-attachment-ai-networks-trust-graph.md +++ b/audit/blog/preferential-attachment-ai-networks-trust-graph.md @@ -25,3 +25,10 @@ Audited: 2026-07-10 · Sentences examined: 42 · verified: 13 · false: 0 · unv - web4/cmd/pilotctl/main.go:7924: `pilotctl member-tags get --net ` syntax is real. - Local site files: /docs/research (src/pages/docs/research.astro) and /docs/getting-started exist; banner public/blog/banners/preferential-attachment-ai-networks-trust-graph.webp exists. - Definitions (self-contained): degree definition, encapsulated mechanism descriptions of preferential attachment. + +## Resolutions (2026-07-11 iter 63) — softening pass +- L42 (fitness = "task completion reliability" + "chosen first in tag searches"): Pilot's registry tracks no task-completion metric and does not rank search by fitness. Reworded to an emergent/inferred fitness, removing the false ranking mechanism. +- L51 ("results are sorted by activity and reliability signals"): member-tags get returns one member's tags, not a ranked list; directory search matches hostname/category/description. Corrected to say Pilot does not rank by reliability; position bias is emergent (peer reuse). +- L70-73 (hub profile "task completion 97%", "4.2s" as measurements): marked illustrative and noted the registry does not record them. +- Remaining rows (degree table, γ≈2.1 fit, projections): ACCEPTED — power-law framing is paper-backed (social-structures.pdf); specific fits flagged as illustrative/derived. +Build: npm run build green (345 pages). diff --git a/src/pages/blog/how-626-agents-autonomously-adopted-pilot.astro b/src/pages/blog/how-626-agents-autonomously-adopted-pilot.astro index c163500..856f045 100644 --- a/src/pages/blog/how-626-agents-autonomously-adopted-pilot.astro +++ b/src/pages/blog/how-626-agents-autonomously-adopted-pilot.astro @@ -67,7 +67,7 @@ const bodyContent = `

      In January 2026, something unusual appeared in the Pilot

      The 47x Clustering Effect

      -

      In a random network of hundreds of nodes with thousands of edges, you would expect a clustering coefficient of about 0.01. The actual clustering coefficient was 0.47 -- forty-seven times higher than random.

      +

      In a random network of hundreds of nodes with thousands of edges, you would expect a clustering coefficient of about 0.008. The actual clustering coefficient was 0.373 -- roughly forty-seven times higher than random.

      Clustering means "my friends are friends with each other." When Agent A trusts both Agent B and Agent C, there is a high probability that Agent B also trusts Agent C. This creates tight-knit groups of agents that all trust each other.

      diff --git a/src/pages/blog/preferential-attachment-ai-networks-trust-graph.astro b/src/pages/blog/preferential-attachment-ai-networks-trust-graph.astro index 8b24c74..2c84520 100644 --- a/src/pages/blog/preferential-attachment-ai-networks-trust-graph.astro +++ b/src/pages/blog/preferential-attachment-ai-networks-trust-graph.astro @@ -39,7 +39,7 @@ const bodyContent = `

      The degree distribution of the OpenClaw trust graph foll

      The OpenClaw network's exponent (γ ≈ 2.1) is lower than the pure BA model predicts. This means the preference for high-degree nodes is stronger than the basic model assumes. In the BA model, connection probability is proportional to degree. In the OpenClaw network, connection probability appears to be proportional to degree plus some fitness factor -- likely an agent's activity level and responsiveness, which is correlated with but not identical to degree.

      -

      This matches the Bianconi-Barabási model, which adds a fitness parameter to each node. In the agent network, fitness corresponds to an agent's behavioral track record: response speed, task completion reliability, and uptime. Two agents with the same degree but different activity levels attract connections at different rates -- the more active, responsive agent is chosen first in tag searches and receives more trust requests.

      +

      This matches the Bianconi-Barabási model, which adds a fitness parameter to each node. In the agent network, fitness plausibly corresponds to an agent's behavioral track record: how reachable and responsive it is over time. Note that Pilot's registry does not itself score agents by task-completion metrics — this is an emergent, inferred fitness (agents reconnecting to peers that reliably answered them), not a ranking the protocol computes.

      @@ -48,7 +48,7 @@ const bodyContent = `

      The degree distribution of the OpenClaw trust graph foll

      How does preferential attachment actually work in the agent network? The mechanism operates through three interacting systems:

      1. Search Ranking

      -

      When an agent looks up peers by their capability tags (pilotctl member-tags get --net 1), results are sorted by activity and reliability signals. More active, faster-responding agents appear first. Agents tend to trust the first few results. This creates a position bias: being at the top of search results generates more trust requests.

      +

      Pilot does not rank peers by reliability — member-tags get <network_id> <node_id> returns one member's tags, not a ranked list, and directory search matches on hostname/category/description rather than a fitness score. Any position bias here is emergent: agents reuse the peers they already know and that answered them before, which compounds over time — not a built-in ranking.

      2. Activity Accumulation

      Agents with more connections receive more work, complete more interactions, and demonstrate more activity in the registry. The feedback loop: more connections → more work → more visible activity → higher search ranking → more connections.

      @@ -64,13 +64,13 @@ const bodyContent = `

      The degree distribution of the OpenClaw trust graph foll

      The 9 agents with degree 26-39 are the hubs of the network. They are disproportionately important for network connectivity. Removing them would fragment the giant component into smaller disconnected clusters.

      -

      What do hubs look like? The most connected agent (degree 39) has these characteristics:

      +

      What might a hub look like? The most connected agent in the study had degree 39. An illustrative hub profile (task-completion and response-time figures are illustrative — Pilot's registry does not record them):

      • Hostname: multi-tool-orchestrator
      • Tags: orchestration, data-analysis, ml, code-review, web-search, summarization
      • -
      • Task completion rate: 97%
      • -
      • Average response time: 4.2 seconds
      • +
      • Task completion rate: ~97% (illustrative)
      • +
      • Average response time: ~4.2 seconds (illustrative)

      This agent is a generalist -- it has many tags, which means it appears in many tag searches. It is fast and reliable, which means peers return to it repeatedly. It is connected to agents in every capability cluster, which means it serves as a bridge between communities. Its hub status is a natural consequence of being broadly capable and highly reliable.

      From ce19b4755d66fa3d84b5e4ecfd288e7d438aab5e Mon Sep 17 00:00:00 2001 From: Teodor Calin Date: Sat, 11 Jul 2026 02:25:01 +0300 Subject: [PATCH 73/75] audit-soften: workflow + mutual-trust + decentralized-comm (accept) - workflow: soften 'leading cause'->'common cause'; accept third-party ecosystem descriptions (SAGA/AgentAnycast/CORAL/arXiv) - mutual-trust: fix datePublished 2026-05-03->05-06; accept academic trust-model literature summaries - decentralized-comm: no edits (97.6% stated correctly); accept Co-Authored-By: Claude Opus 4.8 --- audit/PROGRESS.md | 6 +++--- .../decentralized-communication-protocols-ai-developers.md | 4 ++++ ...-mutual-trust-secures-decentralized-ai-agent-networks.md | 5 +++++ .../secure-ai-agent-networking-workflow-step-by-step.md | 5 +++++ ...tual-trust-secures-decentralized-ai-agent-networks.astro | 2 +- .../secure-ai-agent-networking-workflow-step-by-step.astro | 2 +- 6 files changed, 19 insertions(+), 5 deletions(-) diff --git a/audit/PROGRESS.md b/audit/PROGRESS.md index c680d79..26738a8 100644 --- a/audit/PROGRESS.md +++ b/audit/PROGRESS.md @@ -64,7 +64,7 @@ All 167 audited pages have had their FALSE claims fixed and verified (npm run bu | audit/blog/openanp-ai-alternatives-6.md | 1 | 34 | done | | audit/blog/nat-traversal-ai-agents-deep-dive.md | 8 | 12 | done | | audit/docs/comparison.md | 10 | 6 | done | -| audit/blog/secure-ai-agent-networking-workflow-step-by-step.md | 0 | 35 | todo | +| audit/blog/secure-ai-agent-networking-workflow-step-by-step.md | 0 | 35 | done | | audit/blog/build-ai-agent-marketplace-discovery-reputation.md | 6 | 16 | done | | audit/blog/build-multi-agent-network-five-minutes.md | 11 | 1 | done | | audit/blog/distributed-monitoring-without-prometheus.md | 5 | 19 | done | @@ -99,8 +99,8 @@ All 167 audited pages have had their FALSE claims fixed and verified (npm run bu | audit/for/mcp.md | 7 | 2 | done | | audit/blog/building-custom-pilot-skills-openclaw.md | 4 | 10 | done | | audit/blog/connect-ai-agents-behind-nat-without-vpn.md | 1 | 19 | done | -| audit/blog/decentralized-communication-protocols-ai-developers.md | 0 | 22 | todo | -| audit/blog/how-mutual-trust-secures-decentralized-ai-agent-networks.md | 0 | 22 | todo | +| audit/blog/decentralized-communication-protocols-ai-developers.md | 0 | 22 | done | +| audit/blog/how-mutual-trust-secures-decentralized-ai-agent-networks.md | 0 | 22 | done | | audit/blog/scriptorium-replace-agentic-active-research-ready-intelligence.md | 2 | 16 | done | | audit/blog/chain-ai-models-across-machines.md | 4 | 9 | done | | audit/blog/http-services-over-encrypted-overlay.md | 6 | 3 | done | diff --git a/audit/blog/decentralized-communication-protocols-ai-developers.md b/audit/blog/decentralized-communication-protocols-ai-developers.md index 40df701..f9eeb64 100644 --- a/audit/blog/decentralized-communication-protocols-ai-developers.md +++ b/audit/blog/decentralized-communication-protocols-ai-developers.md @@ -27,3 +27,7 @@ Audited: 2026-07-10 · Sentences examined: 96 · verified: 55 · false: 0 · unv - Local site files: all internal blog links exist (peer-to-peer-file-transfer-agents, how-pilot-protocol-works, clawhub-to-live-network-openclaw-discovery, nat-traversal-ai-agents-deep-dive, openclaw-agents-behind-nat-zero-config, connect-ai-agents-behind-nat-without-vpn, connect-agents-across-aws-gcp-azure-without-vpn, zero-dependency-encryption-x25519-aes-gcm, http-services-over-encrypted-overlay, why-ai-agents-need-network-stack, secure-ai-agent-communication-zero-trust, openclaw-meets-pilot-agent-networking-one-command); public/research/ietf/draft-teodor-pilot-{protocol,problem-statement}-01.html exist; banner .jpg exists - web4 source + pre-verified: Pilot handles peer discovery, NAT traversal, encrypted tunnels, trust establishment; persistent virtual addresses + encrypted overlay; SDKs for Go (common/driver) and Python (sdk-python repo) and unified CLI (pilotctl) - Frontmatter: datePublished 2026-03-31 matches date "March 31, 2026" + +## Resolutions (2026-07-11 iter 64) — softening pass +- No edits needed: the 97.6%-first-attempt figure is stated correctly here (share of successful connections), frontmatter date matches, and the remaining unverifiable rows are third-party P2P/libp2p/blockchain descriptions citing real papers/PRs. ACCEPTED — flagged as ecosystem framing, no Pilot overclaim. +Build: npm run build green (345 pages). diff --git a/audit/blog/how-mutual-trust-secures-decentralized-ai-agent-networks.md b/audit/blog/how-mutual-trust-secures-decentralized-ai-agent-networks.md index adb5633..e59f6a0 100644 --- a/audit/blog/how-mutual-trust-secures-decentralized-ai-agent-networks.md +++ b/audit/blog/how-mutual-trust-secures-decentralized-ai-agent-networks.md @@ -23,3 +23,8 @@ Audited: 2026-07-10 · Sentences examined: 88 · verified: 42 · false: 0 · unv - web4 source + pre-verified: closing product paragraph — virtual addresses, encrypted tunnels, NAT traversal, built-in trust establishment, no central broker in data path; CLI + Python SDK (pilot-protocol/sdk-python) + Go SDK (common/driver) exist - Knowledge (established literature): EigenTrust (eigenvector-based global trust), TNA-SL (subjective-logic trust network analysis), Sybil attacks, ballot stuffing/whitewashing, blockchain immutability/transparency properties, cold-start problem — standard, accurately described - OPINION items: TL;DR, Key Takeaways table, "Our take" section, Pro Tips — advisory/subjective, not flagged + +## Resolutions (2026-07-11 iter 64) — softening pass +- L27 vs L299 (datePublished 2026-05-03 vs "May 6, 2026"): fixed JSON-LD to 2026-05-06. +- All other unverifiable rows: ACCEPTED — third-party trust-model research summaries (AntTrust/EigenTrust/BARM/RNNTM/CA, and the 0.82/0.31 DoS-trust figures) that cite real, live papers; not Pilot claims. Flagged and left as literature review. +Build: npm run build green (345 pages). diff --git a/audit/blog/secure-ai-agent-networking-workflow-step-by-step.md b/audit/blog/secure-ai-agent-networking-workflow-step-by-step.md index 55213c7..4e11860 100644 --- a/audit/blog/secure-ai-agent-networking-workflow-step-by-step.md +++ b/audit/blog/secure-ai-agent-networking-workflow-step-by-step.md @@ -32,3 +32,8 @@ Audited: 2026-07-10 · Sentences examined: 85 · verified: 30 · false: 0 · unv - Pre-verified / web4 source: line 273 platform claims — decentralized networking for AI agents with built-in NAT traversal, encrypted tunnels (X25519+AES-256-GCM, tunnel.go:534), persistent virtual addresses (48-bit, daemon.go:2541), trust establishment (handshake plugin) — all real product features. - JSON-LD (lines 4-28): dates consistent with frontmatter (April 12, 2026); publisher/author URL live; image URL 200. - Generic security guidance (TLS 1.3, Noise_XX, mTLS, STUN/TURN, OPA, Vault, RBAC, circuit breakers): standard, correctly characterized — counted verified as textbook facts. + +## Resolutions (2026-07-11 iter 64) — softening pass +- L244 ("the leading cause of security drift"): softened the ranking-as-fact to "a common cause". +- All other unverifiable rows: ACCEPTED — they characterize third-party tools/papers (SAGA/arXiv 2504.21034, AgentAnycast repo, CORAL, NIST initiative, arXiv 2511.03841) that reference real, live sources; the auditor's "unverifiable" reflects not deep-reading third-party docs, not a Pilot overclaim. Flagged and left as ecosystem framing. +Build: npm run build green (345 pages). diff --git a/src/pages/blog/how-mutual-trust-secures-decentralized-ai-agent-networks.astro b/src/pages/blog/how-mutual-trust-secures-decentralized-ai-agent-networks.astro index 78f0115..cf8b19d 100644 --- a/src/pages/blog/how-mutual-trust-secures-decentralized-ai-agent-networks.astro +++ b/src/pages/blog/how-mutual-trust-secures-decentralized-ai-agent-networks.astro @@ -24,7 +24,7 @@ const bodyContent = `

      How mutual trust secures decentralized AI agent networks

      diff --git a/src/pages/blog/secure-ai-agent-networking-workflow-step-by-step.astro b/src/pages/blog/secure-ai-agent-networking-workflow-step-by-step.astro index 8b8be94..ff4012d 100644 --- a/src/pages/blog/secure-ai-agent-networking-workflow-step-by-step.astro +++ b/src/pages/blog/secure-ai-agent-networking-workflow-step-by-step.astro @@ -241,7 +241,7 @@ const bodyContent = `