···35353636Hydrant consists of several components:
3737- **[`hydrant::ingest::firehose`]**: Connects to an upstream Firehose (Relay) and filters events. It manages the transition between discovery and synchronization.
3838-- **[`hydrant::ingest::worker`]**: Processes buffered Firehose messages concurrently. Verifies signatures, updates repository state, detects gaps for backfill, and persists records.
3838+- **[`hydrant::ingest::worker`]**: Processes buffered Firehose messages concurrently using sharded workers. Verifies signatures, updates repository state (handling account status events like deactivations), detects gaps for backfill, and persists records.
3939- **[`hydrant::crawler`]**: Periodically enumerates the network via `com.atproto.sync.listRepos` to discover new repositories when in full-network mode.
4040-- **[`hydrant::backfill`]**: A dedicated worker that fetches full repository CAR files from PDS instances when a new repo is detected.
4040+- **[`hydrant::resolver`]**: Manages DID resolution and key lookups. Supports multiple PLC directory sources with failover and caching.
4141+- **[`hydrant::backfill`]**: A dedicated worker that fetches full repository CAR files. Uses LIFO prioritization and adaptive concurrency to manage backfill load efficiently.
4142- **[`hydrant::api`]**: An Axum-based XRPC server implementing repository read methods (`getRecord`, `listRecords`) and system stats. It also provides a event stream API via WebSockets.
4243- **Persistence worker** (in `src/main.rs`): Manages periodic background flushes of the LSM-tree and cursor state.
4344···4849## General conventions
49505051### Correctness over convenience
5151-- Model the full error space—no shortcuts or simplified error handling.
5252- Handle all edge cases, including race conditions in the ingestion buffer.
5353- Use the type system to encode correctness constraints.
5454- Prefer compile-time guarantees over runtime checks where possible.
5555+5656+### Error handling
5757+- **Typed Errors**: Define custom error enums (e.g. `ResolverError`, `IngestError`) when callers need to handle specific cases (like rate limits or retries).
5858+- **Diagnostics**: Use `miette::Report` embedded in a `Generic` variant for unexpected errors to maintain diagnostic context.
5959+- **Type Preservation**: Avoid erasing error types with `.into_diagnostic()` in valid code paths; only use it at the top-level application boundary or when the error is truly unrecoverable and needs no special handling.
55605661### Production-grade engineering
5762- Use `miette` for diagnostic-driven error reporting.
···69747075Hydrant uses multiple `fjall` keyspaces:
7176- `repos`: Maps `{DID}` -> `RepoState` (MessagePack).
7272-- `records`: Maps `{DID}|{Collection}|{RKey}` -> `{CID}` (String).
7777+- `records`: Partitioned by collection. Maps `{DID}|{RKey}` -> `{CID}` (Binary).
7378- `blocks`: Maps `{CID}` -> `Block Data` (Raw CBOR).
7479- `events`: Maps `{ID}` (u64) -> `StoredEvent` (MessagePack). This is the source for the JSON stream API.
7580- `cursors`: Maps `firehose_cursor` or `crawler_cursor` -> `Value` (u64/i64 BE Bytes).
7676-- `pending`: Index of DIDs awaiting backfill.
8181+- `pending`: Queue of `{Timestamp}|{DID}` -> `Empty` (Backfill queue).
7782- `resync`: Maps `{DID}` -> `ResyncState` (MessagePack) for retry logic/tombstones.
8383+- `resync_buffer`: Maps `{DID}|{Rev}` -> `Commit` (MessagePack). Used to buffer live events during backfill.
7884- `counts`: Maps `k|{NAME}` or `r|{DID}|{COL}` -> `Count` (u64 BE Bytes).
79858086## Safe commands
81878288### Testing
8389- `nu tests/repo_sync_integrity.nu` - Runs the full integration test suite using Nushell. This builds the binary, starts a temporary instance, performs a backfill against a real PDS, and verifies record integrity.
9090+- `nu tests/verify_crawler.nu` - Verifies full-network crawler functionality using a mock relay.
8491- `nu tests/stream_test.nu` - Tests WebSocket streaming functionality. Verifies both live event streaming during backfill and historical replay with cursor.
8592- `nu tests/authenticated_stream_test.nu` - Tests authenticated event streaming. Verifies that create, update, and delete actions on a real account are correctly streamed by Hydrant in the correct order. Requires `TEST_REPO` and `TEST_PASSWORD` in `.env`.
8693- `nu tests/debug_endpoints.nu` - Tests debug/introspection endpoints (`/debug/iter`, `/debug/get`) and verifies DB content and serialization.
87948895## Rust code style
89969090-- Always try to use variable substitution in `format!` like macros (eg. logging macros like `info!`, `debug!`) like so: `format!("error: {err}")`.
9797+- Prefer variable substitution in `format!` like macros (eg. logging macros like `info!`, `debug!`) like so: `format!("error: {err}")`.
9198- Prefer using let-guard (eg. `let Some(val) = res else { continue; }`) over nested ifs where it makes sense (eg. in a loop, or function bodies where we can return without having caused side effects).
9999+- Prefer functional combinators over explicit matching when it improves readability (eg. `.then_some()`, `.map()`, `.ok_or_else()`).
100100+- Prefer iterator chains (`.filter_map()`, `.flat_map()`) over explicit loops for data transformation.
9210193102## Commit message style
94103