# Plutia Plutia is a deterministic, verifiable PLC mirror for `plc.directory` with signed checkpoints and a proof-serving API. ## Key Capabilities - Mirror and resolver modes. - Pebble-backed state/index storage. - Compressed append-only operation blocks (`zstd`) in mirror mode. - Deterministic canonical operation handling and signature-chain verification. - Signed Merkle checkpoints and DID inclusion proof API. - Corruption detection and restart-safe ingestion. - High-density storage scaling around ~1.2KB/op in benchmarked runs. - ~45x faster than naive replay in benchmarked runs. ## Trust Model - Plutia mirrors data from `https://plc.directory`. - Plutia validates operation signature chains and prev-link continuity according to configured verification policy. - Plutia does **not** alter PLC authority or introduce consensus. - Checkpoints are mirror commitments about what this mirror observed and verified, not global consensus. ## Modes - `mirror`: stores full verifiable operation history (`data/ops/*.zst`) + state + proofs/checkpoints. - `resolver`: stores resolved DID state/index only (no op block archive). ## Quick Start ```bash go test ./... go build ./cmd/plutia ./plutia serve --config=config.yaml ``` ### CLI Commands ```bash plutia serve --config=config.yaml [--max-ops=0] plutia replay --config=config.yaml [--max-ops=0] plutia verify --config=config.yaml --did=did:plc:example plutia snapshot --config=config.yaml plutia bench --config=config.yaml --max-ops=200000 plutia compare --config=config.yaml --remote=https://mirror.example.com plutia version ``` ## Versioning and Reproducible Builds Plutia follows semantic versioning, starting at `v0.1.0`. `plutia version` prints: - `Version` (defaults to `dev` if not injected) - `Commit` - `BuildDate` (UTC RFC3339) - `GoVersion` Build metadata is injected through ldflags: ```bash go build -trimpath \ -ldflags "-X main.version=v0.1.0 -X main.commit=$(git rev-parse --short HEAD) -X main.buildDate=$(date -u +%Y-%m-%dT%H:%M:%SZ)" \ -o ./bin/plutia ./cmd/plutia ``` `make build` provides the same pattern. ## HTTP API - `GET /health` - `GET /metrics` (Prometheus) - `GET /status` (includes build/version metadata) - `GET /did/{did}` - `GET /did/{did}/proof` - `GET /checkpoints/latest` - `GET /checkpoints/{sequence}` ## PLC API Compatibility Plutia includes read-only compatibility endpoints for `plc.directory` API consumers: - `GET /{did}` (returns `application/did+ld+json`) - `GET /{did}/log` - `GET /{did}/log/last` - `GET /{did}/log/audit` - `GET /{did}/data` - `GET /export` (NDJSON, `application/jsonlines`, supports `count` up to `1000`, and `after` RFC3339 filtering based on ingested operation timestamps) For audit/export compatibility fields, `createdAt` is sourced from the mirror's recorded ingest timestamp for each operation reference. Write behavior is intentionally unsupported: - `POST /{did}` returns `405 Method Not Allowed` with `Allow: GET` Verification features are additive extensions and remain available under: - `GET /did/{did}` - `GET /did/{did}/proof` - `GET /checkpoints/latest` - `GET /checkpoints/{sequence}` ## Metrics and Observability Prometheus series exposed at `/metrics` include: - `ingest_ops_total` - `ingest_ops_per_second` - `ingest_lag_ops` - `verify_failures_total` - `checkpoint_duration_seconds` - `checkpoint_sequence` - `disk_bytes_total` - `did_count` Operational hardening includes: - Per-IP token-bucket rate limits (stricter on proof endpoints). - Per-request timeout (default `10s`) with cancellation propagation. - Upstream ingestion retries with exponential backoff and `429` handling. - Graceful SIGINT/SIGTERM shutdown with flush-before-exit behavior. ## Running Your Own Mirror ### System Requirements - Go 1.25+ - SSD-backed storage recommended - RAM: 4GB minimum, 8GB+ recommended for larger throughput - CPU: multi-core recommended for parallel verification workers ### Disk Projections Using benchmarked density (~1.2KB/op total): - 5,000,000 ops: ~6GB - 10,000,000 ops: ~12GB Always keep extra headroom for compaction, checkpoints, and operational buffers. ### Example `config.yaml` See [`config.yaml`](./config.yaml). Core knobs: - `mode` - `verify` - `commit_batch_size` - `verify_workers` - `checkpoint_interval` - `rate_limit.*` - `request_timeout` ### Example `docker-compose.yml` ```yaml services: plutia: image: golang:1.25 working_dir: /app command: sh -lc "go build -trimpath -o /app/bin/plutia ./cmd/plutia && /app/bin/plutia serve --config=/app/config.yaml" ports: - "8080:8080" volumes: - ./:/app - ./data:/app/data restart: unless-stopped ``` ### Upgrade and Backup Guidance - Stop the process cleanly (`SIGTERM`) to flush pending writes. - Back up `data/index`, `data/ops`, and `data/checkpoints` together. - Keep the same `mode` per data directory across restarts. - Upgrade binaries first in staging, then production using the same on-disk data. ## Mirror Comparison Use: ```bash plutia compare --config=config.yaml --remote=https://mirror.example.com ``` The command fetches remote `/checkpoints/latest` and compares: - checkpoint sequence - DID Merkle root - signature presence Behavior: - same sequence + different root => divergence warning and non-zero exit - different sequences => reports which mirror is ahead and exits non-zero - matching sequence/root/signature presence => success ## License MIT OR Apache-2.0