diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..91ae743 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,77 @@ +# CLAUDE.md + +## Project + +`go-p2p` is the P2P networking layer for the Lethean network. Module path: `forge.lthn.ai/core/go-p2p` + +## Commands + +```bash +go test ./... # Run all tests +go test -run TestName ./... # Single test +go test -cover ./node # Coverage for node package +go test -bench . ./... # Benchmarks +go vet ./... # Static analysis +``` + +## Architecture + +Three packages: + +### node/ — P2P Mesh +- **identity.go**: Ed25519 keypair, PEM serialisation, X25519 ECDH, challenge-response auth +- **transport.go**: Encrypted WebSocket (gorilla/websocket + Borg SMSG), handshake, keepalive, dedup, rate limiting +- **peer.go**: Registry with KD-tree scoring (Poindexter), persistence, auth modes (open/allowlist) +- **message.go**: 15 typed protocol messages (handshake, ping, stats, miner, deploy, logs, error) +- **protocol.go**: Response handler with validation and typed parsing +- **worker.go**: Command handlers (ping, stats, miner start/stop, deploy, logs) +- **controller.go**: Remote node operations (connect, command, disconnect) +- **dispatcher.go**: UEPS packet routing skeleton (STUB — needs implementation) +- **bundle.go**: TIM encryption, tarball extraction with Zip Slip defence + +### ueps/ — Wire Protocol (RFC-021) +- **packet.go**: PacketBuilder with TLV encoding and HMAC-SHA256 signing +- **reader.go**: Stream parser with integrity verification +- TLV tags: 0x01-0x05 (header), 0x06 (HMAC), 0xFF (payload marker) +- Header: Version (0x09), CurrentLayer, TargetLayer, IntentID, ThreatScore + +### logging/ — Structured Logger +- Levelled (DEBUG/INFO/WARN/ERROR) with key-value pairs and component scoping + +## Dependencies + +- `github.com/Snider/Borg` — STMF crypto, SMSG encryption, TIM +- `github.com/Snider/Poindexter` — KD-tree for peer selection +- `github.com/Snider/Enchantrix` — Secure environment (via Borg) +- `github.com/gorilla/websocket` — WebSocket transport +- `github.com/google/uuid` — Peer/message IDs +- Lethean codenames: Borg (Secure/Blob), Poindexter (Secure/Pointer), Enchantrix (Secure/Environment) + +## Coding Standards + +- UK English (colour, organisation, centre) +- All types annotated +- Tests use `testify` assert/require +- Licence: EUPL-1.2 +- Security-first: HMAC on all wire traffic, challenge-response auth, Zip Slip defence, rate limiting + +## Test Conventions + +Use table-driven subtests with `t.Run()`. + +## Key Interfaces + +```go +// MinerManager — decoupled miner control (worker.go) +type MinerManager interface { + StartMiner(config map[string]any) error + StopMiner(id string) error + GetStats() map[string]any + GetLogs(id string, lines int) ([]string, error) +} + +// ProfileManager — deployment profiles (worker.go) +type ProfileManager interface { + ApplyProfile(name string, data []byte) error +} +``` diff --git a/FINDINGS.md b/FINDINGS.md new file mode 100644 index 0000000..29acfed --- /dev/null +++ b/FINDINGS.md @@ -0,0 +1,51 @@ +# Findings + +## Code Quality + +- **76 tests in node/, all pass** — but only 42% statement coverage +- **logging/ fully tested** (12 tests, 100% coverage) +- **UEPS has ZERO tests** — 262 lines of crypto wire protocol completely untested +- **`go vet` clean** — no static analysis warnings +- **Zero TODOs/FIXMEs** in codebase + +## Security Posture (Strong) + +- X25519 ECDH key exchange with Borg STMF +- Challenge-response authentication (HMAC-SHA256) +- TLS 1.2+ with hardened cipher suites +- Message deduplication (5-min TTL, prevents amplification) +- Per-peer rate limiting (100 burst, 50 msg/sec) +- Tarball extraction: Zip Slip defence, 100 MB per-file limit, symlink/hardlink rejection +- Peer auth modes: open or public-key allowlist + +## Architecture Strengths + +- Clean separation: identity / transport / peers / protocol / worker / controller +- KD-tree peer selection via Poindexter: [PingMS × 1.0, Hops × 0.7, GeoKM × 0.2, (100-Score) × 1.2] +- Debounced persistence (5s coalesce window for peer registry) +- Buffer pool for JSON encoding (reduces GC pressure) +- Decoupled MinerManager/ProfileManager interfaces + +## Critical Test Gaps + +| File | Lines | Tests | Coverage | +|------|-------|-------|----------| +| identity.go | 290 | 5 tests | Good | +| peer.go | 708 | 19 tests | Good | +| message.go | 237 | 8 tests | Good | +| worker.go | 402 | 10 tests | Good | +| bundle.go | 355 | 9 tests | Good | +| protocol.go | 88 | 5 tests | Good | +| **transport.go** | **934** | **0 tests** | **NONE** | +| **controller.go** | **327** | **0 tests** | **NONE** | +| **dispatcher.go** | **39** | **stub** | **N/A** | +| **ueps/packet.go** | **124** | **0 tests** | **NONE** | +| **ueps/reader.go** | **138** | **0 tests** | **NONE** | + +## Known Issues + +1. **dispatcher.go is a stub** — Contains commented-out UEPS routing code. Threat circuit breaker and intent routing not implemented. +2. **UEPS 0xFF payload length ambiguous** — Relies on external TCP framing, not self-delimiting. Comments note this but no solution implemented. +3. **Potential race in controller.go** — `transport.OnMessage(c.handleResponse)` called during init; if message arrives before pending map ready, could theoretically panic (unlikely in practice). +4. **No resource cleanup on some error paths** — transport.handleWSUpgrade doesn't clean up on handshake timeout; transport.Connect doesn't clean up temp connection on error. +5. **Threat score semantics undefined** — Referenced in dispatcher stub and UEPS header but no scoring/routing logic exists. diff --git a/TODO.md b/TODO.md new file mode 100644 index 0000000..86cc00a --- /dev/null +++ b/TODO.md @@ -0,0 +1,21 @@ +# TODO + +## High Priority — Test Coverage (currently 42%) + +- [ ] **UEPS packet tests** — Zero tests for wire protocol. Need: builder round-trip, HMAC verification, malformed packet rejection, empty payload, oversized payload, max ThreatScore boundary. +- [ ] **Transport tests** — 934 lines untested. Need: WebSocket handshake (accept + reject), SMSG encryption round-trip, connection lifecycle, keepalive timeout, rate limiting, deduplication, protocol version mismatch. +- [ ] **Controller tests** — 327 lines untested. Need: request-response correlation, timeout handling, auto-connect, concurrent requests, GetAllStats parallel execution. + +## Medium Priority — Coverage Target 70%+ + +- [ ] **Dispatcher implementation** — Currently a commented-out stub. Implement UEPS packet routing with threat circuit breaker (drop ThreatScore > 50000) and intent-based dispatch. +- [ ] **Integration test** — Full node-to-node handshake over localhost WebSocket with encrypted message exchange. +- [ ] **Benchmarks** — Peer scoring (KD-tree), UEPS marshal/unmarshal, identity key generation, message serialisation. +- [ ] **bufpool.go tests** — Buffer reuse verification, large buffer handling. + +## Low Priority + +- [ ] **Logging package tests** — Simple but should have coverage for completeness. +- [ ] **Peer discovery** — Currently manual peer registration. Add mDNS or DHT-based discovery. +- [ ] **Connection pooling** — Transport creates fresh connections; add pool for controller reuse. +- [ ] **Error recovery tests** — Handshake timeouts, protocol version mismatch, allowlist rejection, connection drop/reconnect.