From 91146b212a1ff456b1d30285c18d24d29aa93547 Mon Sep 17 00:00:00 2001 From: Snider Date: Sun, 4 Jan 2026 20:04:22 +0000 Subject: [PATCH] feat: Add CLAUDE.md for project guidance and documentation --- CLAUDE.md | 166 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 166 insertions(+) create mode 100644 CLAUDE.md diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..2689436 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,166 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## Project Overview + +Poindexter is a Go library providing: +- **Sorting utilities** with custom comparators (ints, strings, floats, generic types) +- **KDTree** for nearest-neighbor search with multiple distance metrics (Euclidean, Manhattan, Chebyshev, Cosine) +- **Helper functions** for building normalized/weighted KD points (2D/3D/4D/ND) +- **DNS/RDAP tools** for domain, IP, and ASN lookups +- **Analytics** for tree operations and peer selection tracking + +## Build Commands + +```bash +# Run all tests +make test + +# Run tests with race detector +make race + +# Run tests with coverage (writes coverage.out) +make cover + +# Run a single test +go test -run TestFunctionName ./... + +# Build all packages +make build + +# Build with gonum optimized backend +go build -tags=gonum ./... + +# Run tests with gonum backend +go test -tags=gonum ./... + +# Build WebAssembly module +make wasm-build + +# Run benchmarks (writes bench.txt) +make bench + +# Run benchmarks for specific backend +make bench-linear # Linear backend +make bench-gonum # Gonum backend (requires -tags=gonum) + +# Fuzz testing (default 10s) +make fuzz +make fuzz FUZZTIME=30s + +# Lint and static analysis +make lint # requires golangci-lint +make vuln # requires govulncheck + +# CI-parity local run +make ci + +# Format code +make fmt + +# Tidy modules +make tidy +``` + +## Architecture + +### Core Components + +**kdtree.go** - Main KDTree implementation: +- `KDTree[T]` generic struct with payload type T +- `KDPoint[T]` represents points with ID, Coords, and Value +- Query methods: `Nearest()`, `KNearest()`, `Radius()` +- Mutation methods: `Insert()`, `DeleteByID()` +- Distance metrics implement `DistanceMetric` interface + +**Dual Backend System:** +- `kdtree_gonum.go` (build tag `gonum`) - Optimized median-split KD-tree with branch-and-bound pruning +- `kdtree_gonum_stub.go` (default) - Stubs when gonum tag not set +- Linear backend is always available; gonum backend is default when tag is enabled +- Backend selected via `WithBackend()` option or defaults based on build tags + +**kdtree_helpers.go** - Point construction utilities: +- `BuildND()`, `Build2D()`, `Build3D()`, `Build4D()` - Build normalized/weighted KD points +- `ComputeNormStatsND()` - Compute per-axis min/max for normalization +- Supports axis inversion and per-axis weights + +**kdtree_analytics.go** - Operational metrics: +- `TreeAnalytics` - Query/insert/delete counts, timing stats +- `PeerAnalytics` - Per-peer selection tracking for DHT/NAT routing +- Distribution statistics and NAT routing metrics + +**sort.go** - Sorting utilities: +- Type-specific sorts: `SortInts()`, `SortStrings()`, `SortFloat64s()` +- Generic sorts: `SortBy()`, `SortByKey()` +- Binary search: `BinarySearch()`, `BinarySearchStrings()` + +**dns_tools.go** - DNS and RDAP lookup utilities: +- DNS record types and lookup functions +- RDAP (modern WHOIS) for domains, IPs, ASNs +- External tool link generators + +### Examples Directory + +Runnable examples demonstrating KDTree usage patterns: +- `examples/dht_ping_1d/` - 1D DHT with ping latency +- `examples/kdtree_2d_ping_hop/` - 2D with ping + hop count +- `examples/kdtree_3d_ping_hop_geo/` - 3D with geographic distance +- `examples/kdtree_4d_ping_hop_geo_score/` - 4D with trust scores +- `examples/dht_helpers/` - Convenience wrappers for common DHT schemas +- `examples/wasm-browser-ts/` - TypeScript + Vite browser demo + +### WebAssembly + +WASM module in `wasm/main.go` exposes KDTree functionality to JavaScript. Build outputs to `dist/`. + +## Key Patterns + +### KDTree Construction +```go +pts := []poindexter.KDPoint[string]{ + {ID: "A", Coords: []float64{0, 0}, Value: "alpha"}, +} +tree, err := poindexter.NewKDTree(pts, + poindexter.WithMetric(poindexter.EuclideanDistance{}), + poindexter.WithBackend(poindexter.BackendGonum)) +``` + +### Building Normalized Points +```go +pts, err := poindexter.BuildND(items, + func(p Peer) string { return p.ID }, // ID extractor + []func(Peer) float64{getPing, getHops}, // Feature extractors + []float64{1.0, 0.5}, // Per-axis weights + []bool{false, false}) // Inversion flags +``` + +### Distance Metrics +- `EuclideanDistance{}` - L2 norm (default) +- `ManhattanDistance{}` - L1 norm +- `ChebyshevDistance{}` - L-infinity (max) norm +- `CosineDistance{}` - 1 - cosine similarity +- `WeightedCosineDistance{Weights: []float64{...}}` - Weighted cosine + +Note: Cosine metrics use linear backend only; L2/L1/L-infinity work with gonum backend. + +## Testing + +Tests are organized by component: +- `kdtree_test.go`, `kdtree_nd_test.go` - Core KDTree tests +- `kdtree_gonum_test.go` - Gonum backend specific tests +- `kdtree_backend_parity_test.go` - Backend equivalence tests +- `fuzz_kdtree_test.go` - Fuzz targets +- `bench_*.go` - Benchmark suites + +Coverage targets: +```bash +make cover # Summary +make coverfunc # Per-function breakdown +make cover-kdtree # kdtree.go only +make coverhtml # HTML report +``` + +## License + +EUPL-1.2 (European Union Public Licence v1.2) \ No newline at end of file