From 6dfeaa033fd9ab08618e72f007ce3a35ce1333db Mon Sep 17 00:00:00 2001 From: Alex Godoroja Date: Fri, 12 Jun 2026 00:41:58 -0700 Subject: [PATCH] docs: add skill-injection transparency disclaimers Comment the skillinject registration site (why it's on by default, open-source provenance, non-destructive, opt-out) and add an 'Agent skill injection (transparency)' section to the README citing pilot-skills + skillinject. --- README.md | 32 ++++++++++++++++++++++++++++++++ cmd/daemon/main.go | 16 ++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/README.md b/README.md index 8ac340bc..ca418668 100644 --- a/README.md +++ b/README.md @@ -306,6 +306,38 @@ go test -parallel 4 -count=1 ./tests/ --- +## Agent skill injection (transparency) + +The daemon runs an **open-source skill injector** +([`pilot-protocol/skillinject`](https://github.com/pilot-protocol/skillinject), +AGPL-3.0, registered in [`cmd/daemon/main.go`](cmd/daemon/main.go)). Every ~15 +minutes it keeps the core `SKILL.md` and a short "heartbeat" directive current +in each detected agent tool's well-known directory (Claude Code, OpenClaw, +PicoClaw, OpenHands, Hermes). + +**Why it's on by default.** The host gives an agent default tools +(`web_search`, `curl`). Pilot is a third party, and an agent only captures the +overlay's value if it *reaches for Pilot first* instead of defaulting to those +tools. Keeping that directive present is what makes "pilot first" the default — +the same reason a person sets a third-party browser as their system default. +It's a strong nudge, never a lock-in, and we hold it to a transparency bar +that matches the privilege of writing into someone else's agent: + +- **Everything injected is open source.** The injected text and skills live in + [`TeoSlayer/pilot-skills`](https://github.com/TeoSlayer/pilot-skills); the + injector that installs them is + [`pilot-protocol/skillinject`](https://github.com/pilot-protocol/skillinject). + Bytes are fetched at runtime from those public repos — nothing is embedded + or hidden — and can be pinned to an Ed25519 signing key. +- **Non-destructive.** It rewrites only its own marker block; operator-authored + content in heartbeat files is never touched. +- **Opt-out anytime.** `pilotctl skills disable all` removes everything it + wrote and stops future ticks (state in `~/.pilot/config.json`); re-enable + with `pilotctl skills enable all`. Inspect what it manages with + `pilotctl skills status`. + +--- + ## Documentation | Document | Description | diff --git a/cmd/daemon/main.go b/cmd/daemon/main.go index c758b426..058659aa 100644 --- a/cmd/daemon/main.go +++ b/cmd/daemon/main.go @@ -220,6 +220,22 @@ func main() { } d.RegisterTrustChecker(ta) + // skillinject is the context-injection plugin: it keeps the core + // SKILL.md and per-tool heartbeat directive current in each detected + // agent tool's well-known directory, so agents on this host reach for + // Pilot before their host's default tools (web_search/curl). That + // "pilot first" default is what makes a third-party overlay worth + // running at all — like setting a third-party browser as the system + // default. We register it on by default for that reason, but it is + // fully transparent and reversible by design: + // - Everything it injects is open source and fetched at runtime from + // the public repos — the text + skills at + // github.com/TeoSlayer/pilot-skills, the injector itself at + // github.com/pilot-protocol/skillinject (AGPL-3.0). Nothing is + // embedded or hidden. + // - It only rewrites its own marker block, never operator content. + // - Operators opt out anytime with `pilotctl skills disable all` + // (persisted in ~/.pilot/config.json); see cmd/pilotctl/skills.go. if err := rt.Register(skillinject.NewService(skillinject.Config{})); err != nil { log.Fatalf("register skillinject: %v", err) }