# CLAUDE.md ## Overview MCNS (Metacircular Networking Service) is an authoritative DNS server for the Metacircular platform. It serves DNS zones from SQLite, forwards non-authoritative queries to upstream resolvers, and exposes a gRPC/REST management API authenticated through MCIAS. ## Build Commands ```bash make all # vet → lint → test → build make build # go build ./... make test # go test ./... make vet # go vet ./... make lint # golangci-lint run ./... make proto # regenerate gRPC code from .proto files make proto-lint # buf lint + buf breaking make mcns # build mcns binary with version injection make docker # build container image make clean # remove binaries make devserver # build and run against srv/ config ``` Run a single test: `go test ./internal/dns/ -run TestHandlerA` ## Architecture Three listeners on one binary: - **DNS server** (`:53`, UDP+TCP) — serves authoritative zones from SQLite, forwards everything else to upstream resolvers. No authentication. - **REST API** (`:8443`) — management API for zones and records. MCIAS auth. - **gRPC API** (`:9443`) — same management operations. MCIAS auth. Records stored in SQLite. Changes visible to DNS immediately on commit. ## Project Structure ``` cmd/mcns/ CLI entry point (server, snapshot, status) internal/ config/ TOML config with DNS-specific sections db/ SQLite schema, migrations, zone/record queries dns/ DNS server, handler, forwarder, cache server/ REST API routes and handlers grpcserver/ gRPC server, interceptors, service handlers proto/mcns/v1/ Protobuf definitions gen/mcns/v1/ Generated Go code (do not edit) deploy/ Docker, systemd, install scripts, examples ``` ## Ignored Directories - `srv/` — local dev runtime data - `gen/` — regenerated from proto, not hand-edited ## Shared Library MCNS uses `mcdsl` (git.wntrmute.dev/mc/mcdsl) for shared platform packages: auth, db, config, httpserver, grpcserver. These provide MCIAS authentication, SQLite database helpers, TOML config loading, and TLS-configured HTTP/gRPC server scaffolding. ## Testing Patterns - Use stdlib `testing` only. No third-party test frameworks. - Tests use real SQLite databases in `t.TempDir()`. No mocks for databases. ## Key Invariants - **SOA serial format**: YYYYMMDDNN, auto-incremented on every record mutation. If the date prefix matches today, NN is incremented. Otherwise the serial resets to today with NN=01. - **CNAME exclusivity**: Enforced at the DB layer within transactions. A name cannot have both CNAME and A/AAAA records. Attempts to violate this return `ErrConflict`. ## Critical Rules 1. **REST/gRPC sync**: Every REST endpoint must have a corresponding gRPC RPC, updated in the same change. 2. **gRPC interceptor maps**: New RPCs must be added to the correct interceptor map (Public, AuthRequired, AdminRequired). Forgetting this is a security defect. 3. **CNAME exclusivity**: A name cannot have both CNAME and A/AAAA records. Enforced in the database layer within a transaction. 4. **SOA serial**: Auto-incremented on every record mutation. Never manually set or decremented. 5. **DNS has no auth**: Port 53 serves records to any client. All mutations go through the authenticated management API.