Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Code Standards

Deterministic Concurrency

  • BTreeMap over HashMap when iteration order is observable
  • tokio for all concurrency — no thread::spawn
  • No rand crate — all randomness via CrawlSeed -> ChaCha8Rng
  • No Instant::now() in core logic — time from ExecutionEnvelope or caller
  • Atomics for counters/metrics only, never for control flow

Error Handling

  • All errors typed as PalimpsestError variants — no anyhow or eyre in library crates
  • No .unwrap() or .expect() in library code — binary crates may use them in main() only
  • Every ? propagation must preserve the error taxonomy
  • panic! is a bug report, not control flow

Memory and Performance

  • bytes::Bytes for buffers crossing async boundaries
  • Zero-copy: &[u8] > Vec<u8> > String
  • No Clone on large types — use Arc<T> for shared ownership
  • Pre-allocate buffers in hot paths

Serialization

  • serde derive on all types crossing crate boundaries
  • #[serde(rename_all = "snake_case")] on enum variants
  • JSON for human-readable formats
  • Never change serialized field names without a migration plan

Type Design

  • Newtypes for domain concepts: ContentHash, CaptureInstant, CrawlSeed, CrawlContextId
  • Parse, don’t validate: constructors enforce invariants
  • Copy for small values (hashes, timestamps, IDs)
  • #[non_exhaustive] on public enums that may grow

Testing Requirements

  • Every public function has at least one test
  • Property-based tests (proptest) for data transformation functions
  • Snapshot tests (insta) for serialization formats
  • Determinism tests: same seed = byte-identical output