# FeltDB Server

This crate is the first network adapter over the canonical `feltdb` runtime. It does not own a
second state store: every HTTP mutation calls `FeltDb::insert`, `FeltDb::update`, or
`FeltDb::delete`, producing the same operations, vector-clock updates, durable log entries, and
reactive events as an embedded mutation.

Run it with:

```sh
cargo run -p feltdb-server -- \
  --host 127.0.0.1 \
  --port 7700 \
  --namespace my-app \
  --data ./data/feltdb.log
```

For a customer-facing process, create a namespace-bound key and enable authentication:

```sh
cargo run -p feltdb-server -- keys create \
  --keys ./data/api-keys.json \
  --name application \
  --namespace my-app \
  --scope state:read,state:write,events:read

cargo run -p feltdb-server -- \
  --namespace my-app \
  --data ./data/feltdb.log \
  --keys ./data/api-keys.json \
  --auth
```

The secret is printed once; only its Argon2 hash is stored. Send it as
`Authorization: Bearer <key>`. Use `keys list` to inspect safe key metadata and
`keys revoke --id <id>` to revoke a key. Restart a running server after changing its key file.

Implemented in this slice:

- `GET /health`
- `GET /runtime`
- collection list/create/get/update/delete endpoints
- `GET /events` as a server-sent event stream
- durable, hashed API keys with namespace and `state:read`, `state:write`, or `events:read` scopes
- `GET /metrics` request, authorization, state, and event counters
- authenticated `POST /sync/pull` and `POST /sync/push` operation exchange
- durable, transitive operation history with content-hash verification, deduplication, and gap rejection

Peer credentials should be separate from application credentials and use the `sync:read` and
`sync:write` scopes. Pull requests contain the caller's per-origin `versions` map. Push requests
contain the target `namespace` and operations returned by pull. This version-vector exchange
preserves original operation identity through relays instead of translating replicated writes into
new local mutations.

To maintain a continuous bidirectional session, configure one or more peers and provide the peer
key through an environment variable (never a command-line argument):

```sh
export FELTDB_PEER_TOKEN='fdb_live_...'
feltdb-server --namespace my-app --peer https://peer-a.example --peer https://peer-b.example
```

Each session pulls and pushes missing operations, advertises the successfully contacted peer to the
runtime registry, and retries failures with exponential backoff capped at 30 seconds. The polling
interval defaults to two seconds and can be changed with `--sync-interval-ms`.

Successful pushes durably persist the remote peer's per-origin acknowledgement vector. Once every
configured peer acknowledges an operation, compaction atomically replaces that history with a
content-hashed state snapshot. A pristine peer bootstraps from `GET /sync/snapshot`, installs the
snapshot's state and causal high-water marks, then resumes ordinary operation exchange without
replaying pruned history or encountering sequence gaps. Nodes with independent local history are
never overwritten by snapshot bootstrap.
- `FeltDB-Protocol` compatibility rejection
- 1 MiB request limit, identifier validation, graceful shutdown, and structured HTTP tracing
- durable deletion tombstones that survive process restart

The runtime discovery response explicitly marks acquisition, remote capabilities, workflows,
agents, and provenance as unavailable until those systems are connected to this same operation
boundary. The server must never advertise simulated functionality as healthy.
