# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## Project Overview

MCR (Metacircular Container Registry) is a container registry service integrated with MCIAS for authentication and authorization. It is part of the Metacircular Dynamics platform. See `ARCHITECTURE.md` for the full specification (must be written before implementation begins).

**Priorities (in order):** security, robustness, correctness.

## Build Commands

```bash
make all          # vet → lint → test → build
make mcr          # build binary with version injection
make build        # compile all packages
make test         # run all tests
make vet          # go vet
make lint         # golangci-lint
make proto        # regenerate gRPC code from proto definitions
make proto-lint   # buf lint + breaking change detection
make devserver    # build and run locally with srv/mcr.toml
make clean        # remove built binaries
make docker       # build container image
```

Run a single test:
```bash
go test ./internal/server -run TestPushManifest
```

## Tech Stack

- **Language:** Go 1.25+, `CGO_ENABLED=0`, statically linked
- **Module path:** `git.wntrmute.dev/kyle/mcr`
- **Database:** SQLite via `modernc.org/sqlite` (pure-Go, no CGo)
- **Config:** TOML via `go-toml/v2`, env overrides via `MCR_*`
- **APIs:** REST (chi) + gRPC (protobuf), kept in sync
- **Web UI:** Go `html/template` + htmx, embedded via `//go:embed`
- **Auth:** Delegated to MCIAS — no local user database
- **Linting:** golangci-lint v2 with `.golangci.yaml`
- **Testing:** stdlib `testing` only, real SQLite in `t.TempDir()`

## Architecture

- REST and gRPC APIs over HTTPS/TLS 1.3 (minimum, no exceptions)
- SQLite with WAL mode, `foreign_keys=ON`, `busy_timeout=5000`
- Write-through pattern: gRPC mutations write to DB first, then update in-memory state
- Every REST endpoint must have a corresponding gRPC RPC, and vice versa
- gRPC interceptor maps (`authRequiredMethods`, `adminRequiredMethods`) enforce access control — adding an RPC without adding it to the correct maps is a security defect
- Web UI runs as a separate binary (`mcr-web`) that talks to the API server via gRPC — no direct DB access
- Runtime data in `/srv/mcr/`, never committed to the repo

## Package Structure

- `cmd/mcr/` — CLI entry point (cobra subcommands: server, init, status, snapshot)
- `cmd/mcr-web/` — Web UI entry point
- `internal/auth/` — MCIAS integration (token validation, 30s cache by SHA-256)
- `internal/config/` — TOML config loading and validation
- `internal/db/` — SQLite setup, migrations (idempotent, tracked in `schema_migrations`)
- `internal/server/` — REST API server, chi routes, middleware
- `internal/grpcserver/` — gRPC server, interceptors, service handlers
- `internal/webserver/` — Web UI server, template routes, htmx handlers
- `proto/mcr/v1/` — Protobuf definitions (source of truth)
- `gen/mcr/v1/` — Generated gRPC code (never edit by hand)
- `web/` — Templates and static files, embedded via `//go:embed`
- `deploy/` — Docker, systemd units, install scripts, example config

## Development Workflow

1. Check PROGRESS.md for current state and next steps (create it if it doesn't exist)
2. Design first — write or update `ARCHITECTURE.md` before implementing
3. Implement, test, lint, commit, update PROGRESS.md
4. Pre-push: `make all` must pass clean

## Critical Rules

- API sync: every REST endpoint has a matching gRPC RPC, updated in the same change
- No local user database — all auth delegated to MCIAS
- Default deny — unauthenticated and unauthorized requests always rejected
- No custom crypto — use stdlib `crypto/...` or well-audited packages only
- TLS 1.3 minimum, no fallback ciphers
- Never log secrets (passwords, tokens, keys)
- Security-sensitive changes must include a `Security:` line in the commit body
- Migrations are idempotent and never modified after deployment
- Generated code in `gen/` is never edited by hand
- Verify fixes by running `go build ./...` and `go test ./...` before claiming resolution

## Key Documents

- `ARCHITECTURE.md` — Full system specification (required before implementation)
- `PROJECT_PLAN.md` — Implementation phases with acceptance criteria
- `PROGRESS.md` — Development progress tracking (update after each step)
- `RUNBOOK.md` — Operational procedures (to be written)
- `../engineering-standards.md` — Platform-wide standards (authoritative reference)
