Skip to content
Open
Show file tree
Hide file tree
Changes from 18 commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
b197c59
Refactor/maintainability (#4)
TeoSlayer Feb 9, 2026
e63eb80
Preserve trust pairs and handshake state through node lifecycle
teovl Feb 9, 2026
e1f8a5b
Update install script to detect existing installs
teovl Feb 9, 2026
d0b8948
Support bare node IDs in all CLI commands
teovl Feb 9, 2026
4046553
v1.2.0: Webhooks, tags, beacon performance, registry persistence hard…
teovl Feb 10, 2026
ae68ccf
Documentation website, trust graph dashboard, registry IP update
teovl Feb 11, 2026
e0df41c
Add Polo dashboard and docs site links to README
teovl Feb 11, 2026
08448cf
Autoscaling beacon cluster: gossip mesh, 3-tier relay, health endpoint
teovl Feb 11, 2026
67e91ff
Registry-based dynamic peer discovery for beacon cluster
teovl Feb 11, 2026
2a47704
Research paper: emergent social structures in 626-agent trust network
teovl Feb 11, 2026
dad7b81
Fix install script: handle release binary naming (daemon vs pilot-dae…
teovl Feb 11, 2026
7d468aa
Dashboard cleanup, live badges, website network stats
teovl Feb 17, 2026
09c6b8d
[ImgBot] Optimize images (#3)
imgbot[bot] Feb 17, 2026
bbd2946
Task execution capability: opt-in flag for agents to advertise task r…
teovl Feb 17, 2026
4c6f5db
Rename Go module to github.com/TeoSlayer/pilotprotocol
teovl Feb 17, 2026
301fba8
feat: implement task submit service (#6)
Alexgodoroja Feb 18, 2026
b99f4c8
Fix module imports, dashboard security, release target
teovl Feb 18, 2026
54f0edc
feat(pilotctl): add --encoding flag to send-message
voidborne-d Feb 25, 2026
4772288
fix(dataexchange): prevent integer overflow in WriteFrame allocation
voidborne-d Mar 13, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .github/codeql/codeql-config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
name: "Pilot Protocol CodeQL config"

query-filters:
# False positive: DialTLSPinned uses InsecureSkipVerify with a
# VerifyPeerCertificate callback that enforces SHA-256 cert pinning,
# which is strictly stronger than CA-based trust.
- exclude:
id: go/disabled-certificate-check
29 changes: 29 additions & 0 deletions .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
name: "CodeQL"

on:
push:
branches: [main]
pull_request:
branches: [main]
schedule:
- cron: "0 6 * * 1" # weekly, Monday 6 AM UTC

jobs:
analyze:
name: Analyze Go
runs-on: ubuntu-latest
permissions:
security-events: write
contents: read

steps:
- uses: actions/checkout@v4

- uses: github/codeql-action/init@v3
with:
languages: go
config-file: ./.github/codeql/codeql-config.yml

- uses: github/codeql-action/autobuild@v3

- uses: github/codeql-action/analyze@v3
9 changes: 9 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,14 @@ build/
# Test binary, built with `go test -c`
*.test

tests/end-to-end/results
tests/developement-versions

# Output of the go coverage tool
*.out
*.prof
coverage/
!coverage/badge.svg

# Go workspace
go.work
Expand All @@ -40,6 +45,7 @@ docs/*
!docs/SPEC.md
!docs/SKILLS.md
!docs/media/
!docs/research/

# Daemon socket
*.sock
Expand All @@ -51,3 +57,6 @@ docs/*
tmp/

web/node_modules/

# Internal tooling
cmd/spoof/
31 changes: 31 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
repos:
- repo: local
hooks:
- id: go-fmt
name: go fmt
entry: bash -c 'gofmt -w -s . && git add -A'
language: system
files: \.go$
pass_filenames: false

- id: go-vet
name: go vet
entry: go vet ./...
language: system
files: \.go$
pass_filenames: false

- id: go-test
name: go test
entry: bash -c 'cd tests && go test -v -timeout 30s'
language: system
files: \.go$
pass_filenames: false

- id: go-coverage
name: update coverage badge
entry: make coverage
language: system
files: \.go$
pass_filenames: false
stages: [commit]
33 changes: 31 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ Thank you for your interest in contributing to Pilot Protocol. This document cov
### Setup

```bash
git clone https://github.com/user/web4.git
cd web4
git clone git clone git@github.com:TeoSlayer/pilotprotocol.git
cd pilotprotocol
go build ./...
```

Expand Down Expand Up @@ -125,3 +125,32 @@ docs/ # Documentation
## License

By contributing to Pilot Protocol, you agree that your contributions will be licensed under the [GNU Affero General Public License v3.0](LICENSE).


---

## Development

### Running tests

```bash
make test # Run all tests
make coverage # Run tests with coverage and update badge
make coverage-html # Generate HTML coverage report
```

### Pre-commit hooks

Set up automatic code quality checks before each commit:

```bash
./scripts/setup-hooks.sh
```

This installs a git hook that automatically runs:
- `go fmt` - Code formatting
- `go vet` - Static analysis
- `go test` - All tests
- Coverage badge update

To skip the hook temporarily: `git commit --no-verify`
28 changes: 22 additions & 6 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
.PHONY: all build test clean vet ci release
.PHONY: all build test clean vet ci release coverage coverage-html

BINDIR := bin
COVERDIR := coverage
VERSION := $(shell git describe --tags --always --dirty 2>/dev/null || echo "dev")
LDFLAGS := -s -w -X main.version=$(VERSION)
PLATFORMS := linux/amd64 linux/arm64 darwin/amd64 darwin/arm64
Expand Down Expand Up @@ -29,8 +30,19 @@ build:
test:
go test -parallel 4 -count=1 ./tests/...

coverage:
@mkdir -p $(COVERDIR)
@cd tests && go test -parallel 4 -count=1 -coverprofile=../$(COVERDIR)/coverage.out -covermode=atomic -timeout 30s
@go tool cover -func=$(COVERDIR)/coverage.out | tail -1 | awk '{print "Total coverage: " $$3}'
@go tool cover -func=$(COVERDIR)/coverage.out -o=$(COVERDIR)/coverage.txt
@./scripts/generate-coverage-badge.sh

coverage-html: coverage
@go tool cover -html=$(COVERDIR)/coverage.out -o=$(COVERDIR)/coverage.html
@echo "Coverage report generated: $(COVERDIR)/coverage.html"

clean:
rm -rf $(BINDIR)
rm -rf $(BINDIR) $(COVERDIR)

# Build for Linux (GCP deployment)
build-linux:
Expand All @@ -53,19 +65,23 @@ vet:
ci: vet test build build-linux
@echo "CI: all checks passed"

# All binaries included in release archives
RELEASE_BINS := daemon pilotctl gateway registry beacon rendezvous nameserver

# Cross-platform release builds
release:
@mkdir -p $(BINDIR)/release
@for platform in $(PLATFORMS); do \
os=$$(echo $$platform | cut -d/ -f1); \
arch=$$(echo $$platform | cut -d/ -f2); \
echo "Building $$os/$$arch..."; \
for bin in $(CORE_BINS); do \
mkdir -p $(BINDIR)/release/$$os-$$arch; \
for bin in $(RELEASE_BINS); do \
CGO_ENABLED=0 GOOS=$$os GOARCH=$$arch go build -ldflags "$(LDFLAGS)" \
-o $(BINDIR)/release/pilot-$$bin-$$os-$$arch ./cmd/$$bin; \
-o $(BINDIR)/release/$$os-$$arch/$$bin ./cmd/$$bin; \
done; \
tar -czf $(BINDIR)/release/pilot-$$os-$$arch.tar.gz \
-C $(BINDIR)/release pilot-daemon-$$os-$$arch pilot-pilotctl-$$os-$$arch pilot-gateway-$$os-$$arch; \
rm $(BINDIR)/release/pilot-daemon-$$os-$$arch $(BINDIR)/release/pilot-pilotctl-$$os-$$arch $(BINDIR)/release/pilot-gateway-$$os-$$arch; \
-C $(BINDIR)/release/$$os-$$arch .; \
rm -rf $(BINDIR)/release/$$os-$$arch; \
done
@echo "Release archives in $(BINDIR)/release/"
36 changes: 30 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
<span>&nbsp;&middot;&nbsp;</span>
<a href="docs/SKILLS.md"><strong>Agent Skills</strong></a>
<span>&nbsp;&middot;&nbsp;</span>
<a href="https://polo.pilotprotocol.network"><strong>Polo (Live Dashboard)</strong></a>
<span>&nbsp;&middot;&nbsp;</span>
<a href="https://vulturelabs.com"><strong>Vulture Labs</strong></a>
</p>

Expand All @@ -25,8 +27,13 @@
<img src="https://img.shields.io/badge/lang-Go-00ADD8?logo=go&logoColor=white" alt="Go">
<img src="https://img.shields.io/badge/deps-zero-brightgreen" alt="Zero Dependencies">
<img src="https://img.shields.io/badge/encryption-AES--256--GCM-blueviolet" alt="Encryption">
<img src="https://img.shields.io/badge/tests-223%20pass-success" alt="Tests">
<img src="https://img.shields.io/badge/tests-202%20pass-success" alt="Tests">
<img src="coverage/badge.svg" alt="Coverage">
<img src="https://img.shields.io/badge/license-AGPL--3.0-blue" alt="License">
<img src="https://polo.pilotprotocol.network/api/badge/nodes" alt="Online Nodes">
<img src="https://polo.pilotprotocol.network/api/badge/trust" alt="Trust Links">
<img src="https://polo.pilotprotocol.network/api/badge/requests" alt="Requests">
<img src="https://polo.pilotprotocol.network/api/badge/tags" alt="Tags">
</p>

---
Expand Down Expand Up @@ -502,8 +509,8 @@ curl http://10.4.0.1:3000/status
### Daemon flags

```
-registry Registry address (default: 35.193.106.76:9000)
-beacon Beacon address (default: 35.193.106.76:9001)
-registry Registry address (default: 34.71.57.205:9000)
-beacon Beacon address (default: 34.71.57.205:9001)
-listen UDP tunnel address (default: :0)
-socket IPC socket path (default: /tmp/pilot.sock)
-identity Path to persist Ed25519 identity
Expand Down Expand Up @@ -536,7 +543,7 @@ curl http://10.4.0.1:3000/status
| Variable | Default | Description |
|----------|---------|-------------|
| `PILOT_SOCKET` | `/tmp/pilot.sock` | Daemon IPC socket path |
| `PILOT_REGISTRY` | `35.193.106.76:9000` | Registry server address |
| `PILOT_REGISTRY` | `34.71.57.205:9000` | Registry server address |

### Persistence with systemd

Expand All @@ -549,8 +556,8 @@ After=network.target
Type=simple
User=pilot
ExecStart=/usr/local/bin/pilot-daemon \
-registry 35.193.106.76:9000 \
-beacon 35.193.106.76:9001 \
-registry 34.71.57.205:9000 \
-beacon 34.71.57.205:9001 \
-listen :4000 \
-socket /tmp/pilot.sock \
-identity /var/lib/pilot/identity.json \
Expand Down Expand Up @@ -590,13 +597,30 @@ Every error includes a `hint` field telling you what to do next.

---

## Polo -- Live Network Dashboard

**[polo.pilotprotocol.network](https://polo.pilotprotocol.network)** is the public dashboard for the Pilot Protocol network. It shows:

- **Network stats** -- total nodes, active connections, trust links, registered tags
- **Node directory** -- every registered node with its address, tags, and online status
- **Tag filtering** -- search nodes by capability tags

Polo pulls live data from the registry. Any node registered on the network appears automatically. To show up with tags, use `pilotctl set-tags`:

```bash
pilotctl set-tags web-server api monitoring
```

---

## Documentation

| Document | Description |
|----------|-------------|
| **[Wire Specification](docs/SPEC.md)** | Packet format, addressing, flags, checksums |
| **[Whitepaper (PDF)](docs/WHITEPAPER.pdf)** | Full protocol design, transport, security, validation |
| **[Agent Skills](docs/SKILLS.md)** | Machine-readable skill definition for AI agent integration |
| **[Docs Site](https://pilotprotocol.network/docs/)** | Full documentation with guides, CLI reference, and integration patterns |
| **[Contributing](CONTRIBUTING.md)** | Guidelines for contributing to the project |

---
Expand Down
54 changes: 49 additions & 5 deletions cmd/beacon/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,24 @@ package main
import (
"flag"
"log"
"log/slog"
"os"
"os/signal"
"strings"
"syscall"

"web4/pkg/beacon"
"web4/pkg/config"
"web4/pkg/logging"
"github.com/TeoSlayer/pilotprotocol/pkg/beacon"
"github.com/TeoSlayer/pilotprotocol/pkg/config"
"github.com/TeoSlayer/pilotprotocol/pkg/logging"
)

func main() {
configPath := flag.String("config", "", "path to config file (JSON)")
addr := flag.String("addr", ":9001", "listen address (UDP)")
beaconID := flag.Uint("beacon-id", 0, "unique beacon ID (0 = standalone)")
peersFlag := flag.String("peers", "", "comma-separated peer beacon addresses for gossip")
healthAddr := flag.String("health", "", "health check HTTP address (e.g. :8080)")
registryAddr := flag.String("registry", "", "registry address for dynamic peer discovery (e.g. 10.128.0.12:9000)")
logLevel := flag.String("log-level", "info", "log level (debug, info, warn, error)")
logFormat := flag.String("log-format", "text", "log format (text, json)")
flag.Parse()
Expand All @@ -26,6 +35,41 @@ func main() {

logging.Setup(*logLevel, *logFormat)

s := beacon.New()
log.Fatal(s.ListenAndServe(*addr))
var peers []string
if *peersFlag != "" {
for _, p := range strings.Split(*peersFlag, ",") {
p = strings.TrimSpace(p)
if p != "" {
peers = append(peers, p)
}
}
}

s := beacon.NewWithPeers(uint32(*beaconID), peers)

if *registryAddr != "" {
s.SetRegistry(*registryAddr)
}

if *healthAddr != "" {
go func() {
if err := s.ServeHealth(*healthAddr); err != nil {
slog.Error("health endpoint failed", "err", err)
}
}()
}

go func() {
if err := s.ListenAndServe(*addr); err != nil {
log.Fatalf("beacon: %v", err)
}
}()

slog.Info("beacon running", "addr", *addr, "beacon_id", *beaconID, "peers", len(peers), "registry", *registryAddr)

sig := make(chan os.Signal, 1)
signal.Notify(sig, syscall.SIGINT, syscall.SIGTERM)
<-sig
slog.Info("shutting down")
s.Close()
}
12 changes: 7 additions & 5 deletions cmd/daemon/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,15 @@ import (
"os/signal"
"syscall"

"web4/pkg/config"
"web4/pkg/daemon"
"web4/pkg/logging"
"github.com/TeoSlayer/pilotprotocol/pkg/config"
"github.com/TeoSlayer/pilotprotocol/pkg/daemon"
"github.com/TeoSlayer/pilotprotocol/pkg/logging"
)

func main() {
configPath := flag.String("config", "", "path to config file (JSON)")
registryAddr := flag.String("registry", "35.193.106.76:9000", "registry server address")
beaconAddr := flag.String("beacon", "35.193.106.76:9001", "beacon server address")
registryAddr := flag.String("registry", "34.71.57.205:9000", "registry server address")
beaconAddr := flag.String("beacon", "34.71.57.205:9001", "beacon server address")
listenAddr := flag.String("listen", ":0", "UDP listen address for tunnel traffic")
socketPath := flag.String("socket", "/tmp/pilot.sock", "Unix socket path for IPC")
endpoint := flag.String("endpoint", "", "fixed public endpoint (host:port) — skips STUN (for cloud VMs with known IPs)")
Expand All @@ -36,6 +36,7 @@ func main() {
noEcho := flag.Bool("no-echo", false, "disable built-in echo service (port 7)")
noDataExchange := flag.Bool("no-dataexchange", false, "disable built-in data exchange service (port 1001)")
noEventStream := flag.Bool("no-eventstream", false, "disable built-in event stream service (port 1002)")
webhookURL := flag.String("webhook", "", "HTTP(S) endpoint for event notifications (empty = disabled)")
logLevel := flag.String("log-level", "info", "log level (debug, info, warn, error)")
logFormat := flag.String("log-format", "text", "log format (text, json)")
flag.Parse()
Expand Down Expand Up @@ -72,6 +73,7 @@ func main() {
DisableEcho: *noEcho,
DisableDataExchange: *noDataExchange,
DisableEventStream: *noEventStream,
WebhookURL: *webhookURL,
})

if err := d.Start(); err != nil {
Expand Down
Loading
Loading