PRESSURECRAFT
On this page
- Why Pressurecraft?
- The Five Principles
- 1. Functional Core, Imperative Shell
- 2. Make Illegal States Unrepresentable
- 3. Parse, Don’t Validate
- 4. Assertion Density
- 5. Explicit Control Flow
- Code Style
- Naming Conventions
- Function Structure
- Module Organization
- Production Assertion Strategy
- Error Handling
- Error Types
- No Unwrap in Library Code
- Expect Over Unwrap for True Invariants
- Dependency Policy
- Tier 1: Trusted Core
- Tier 2: Carefully Evaluated
- Tier 3: Cryptography
- Dependency Checklist
- The Deep Time Perspective
- Closing
“Diamonds form 150 kilometers below the surface, at pressures exceeding 50 kilobars and temperatures above 1000°C. They remain there for billions of years—unchanged, stable, enduring. Only rare volcanic eruptions through kimberlite pipes bring them to the surface.”
Diamonds don’t become valuable by accident. They’re forged under immense pressure over geological time. The pressure doesn’t break them—it creates their structure. Their hardness, their clarity, their brilliance—all products of conditions that would destroy lesser materials.
This document is about writing code with the same property.
Why Pressurecraft?
“Simplicity is prerequisite for reliability.” — Edsger W. Dijkstra
Kimberlite is a compliance-first database for regulated industries—healthcare, finance, legal. Our users stake their businesses on our correctness. An invalid state is not a bug to fix in the next sprint; it is a fault line waiting to rupture during an audit, a lawsuit, or a breach investigation.
Our architecture mirrors the geology:
- The append-only log is the stable core—immutable, pressure-forged, enduring
- Kimberlite is the system that extracts value from that core
- Projections are the diamonds—valuable, structured artifacts derived from the unchanging log
We optimize for three things, in this order:
- Correctness — Code that cannot be wrong is better than code that is tested to be right.
- Auditability — Every state change must be traceable. If it’s not in the log, it didn’t happen.
- Simplicity — Every abstraction is a potential crack, invisible until stress reveals it.
We do not optimize for writing speed. We optimize for reading over decades. The code you write today will be read by auditors, regulators, and engineers who haven’t been hired yet. They will thank you or curse you based on what you leave behind.
There is no “quick fix” in Kimberlite. There is only correct or fractured.
The Five Principles
1. Functional Core, Imperative Shell
“The purpose of abstraction is not to be vague, but to create a new semantic level in which one can be absolutely precise.” — Edsger W. Dijkstra
This is a mandatory pattern for all Kimberlite code.
Diamonds do not change in the depths. Earthquakes, volcanic eruptions, tectonic shifts—these happen at the surface, not in the crystalline core. The core remains inert, unchanged, pure.
Our kernel follows the same principle. It is a pure, deterministic state machine. All side effects—I/O, clocks, randomness—live at the edges, in the imperative shell. The shell handles the chaos of the real world. The core remains crystalline.
The Core (Pure):
- Takes commands and current state
- Returns new state and effects to execute
- No I/O, no clocks, no randomness
- Trivially testable with unit tests
The Shell (Impure):
- Handles RPC, authentication, network I/O
- Manages storage, file handles, sockets
- Provides clocks, random numbers when needed
- Executes effects produced by the core
Why This Matters:
- Deterministic replay: Given the same log, we get the same state. Always. This is how we prove correctness to auditors.
- Testing: The core can be tested exhaustively without mocks.
- Simulation: We can run thousands of simulated nodes in a single process.
- Debugging: Reproduce any bug by replaying the log.
Function-Level FCIS:
// GOOD: Pure core function — the unchanging diamond
// BAD: Impure core function — cracks in the crystal
Struct-Level FCIS (for types requiring randomness):
Every type that needs I/O must separate pure core from impure shell. This is structural—the pattern is encoded in the type itself.
The pattern is always the same:
from_random_bytes()— Pure core,pub(crate)to prevent weak inputfrom_bytes()— Pure restoration from storagegenerate()— Impure shell that calls the pure core
2. Make Illegal States Unrepresentable
“I call it my billion-dollar mistake. It was the invention of the null reference in 1965.” — Tony Hoare
A flaw in a diamond is a place where invalid structures can exist. The goal is to eliminate flaws entirely—to build structures that cannot fracture because the fracture planes don’t exist.
Use Rust’s type system to prevent bugs at compile time, not runtime. If the compiler accepts it, it should be correct. If it’s incorrect, the compiler should reject it.
Use enums over booleans:
// BAD: Boolean blindness — two bools = four states, only three are valid
// GOOD: States are explicit — impossible to be admin but not authenticated
Use newtypes over primitives:
// BAD: Three u64s — which is which?
;
// GOOD: Types prevent mixups at compile time
;
Use Option/Result over sentinel values:
// BAD: Magic value — what if -1 is a valid offset someday?
const NOT_FOUND: i64 = -1;
;
// GOOD: Explicit absence
;
Encode state machines in types — compile-time crystallization:
// BAD: Runtime state checking — easy to forget, easy to get wrong
// GOOD: Compile-time state enforcement — invalid transitions don't compile
3. Parse, Don’t Validate
“Data dominates. If you’ve chosen the right data structures and organized things well, the algorithms will almost always be self-evident.” — Rob Pike
Carbon becomes diamond through pressure and time. Once crystallized, it doesn’t need to be re-validated as diamond. The transformation is permanent.
Validation is checking that data meets constraints. Parsing is transforming data into a representation that cannot violate those constraints. Validate once, at the boundary. Parse into types that carry the proof of validity with them.
The Pattern:
- Untrusted input arrives (bytes, JSON, user strings)
- Parse into strongly-typed representation (or reject with clear error)
- All internal code works with known-valid types
- Never re-validate what’s already been parsed
// BAD: Validate repeatedly — carbon that never crystallizes
// GOOD: Parse once, use safely — diamond
;
Apply at every boundary:
- Network: Parse wire protocol into Request types
- Storage: Parse bytes into Record types
- Config: Parse TOML/JSON into Config types
- User input: Parse strings into domain types
The boundary is where the pressure is applied. Everything inside is crystalline.
4. Assertion Density
“Program testing can be used to show the presence of bugs, but never to show their absence.” — Edsger W. Dijkstra
Geologists don’t wait for eruptions to discover the earth’s structure. They deploy seismic sensors—instruments that detect structural problems before they propagate into catastrophe.
Assertions are our seismic sensors. Every function should have at least two: a precondition (what must be true when we enter) and a postcondition (what must be true when we leave). These aren’t just checks—they’re executable documentation of invariants.
Assertions Document Invariants:
Paired Assertions — write site and read site:
Like core samples that verify the geological record, paired assertions verify that what was written is what gets read.
// Write site
// Read site — paired assertion verifies write
Debug vs Release:
assert!()— Critical invariants. Always checked. The ground truth.debug_assert!()— Expensive checks. Debug builds only. The deep survey.
5. Explicit Control Flow
“There are two ways of constructing a software design: One way is to make it so simple that there are obviously no deficiencies, and the other way is to make it so complicated that there are no obvious deficiencies.” — C.A.R. Hoare
Deep geological processes are where pressure builds invisibly until the eruption arrives. Hidden control flow is the software equivalent: callbacks, implicit recursion, unbounded loops. You don’t see the problem building until it’s too late.
Control flow should be visible and bounded. No hidden depths. No unexpected collapses.
No Recursion — convert to explicit iteration with bounds:
// BAD: Unbounded recursion — hidden pressure
// GOOD: Explicit iteration with known depth
Push Ifs Up, Fors Down — clear layering:
Like the thermal structure of the Earth—distinct layers with known boundaries—control flow should stratify cleanly. Decisions at the top, iteration at the bottom.
// BAD: Conditionals buried in the depths
// GOOD: Decisions at the surface, iteration below
Bounded Loops — known depths:
// BAD: Unbounded retry — drilling forever
loop
// GOOD: Explicit bounds — we know how deep we'll go
const MAX_RETRIES: usize = 3;
for attempt in 0..MAX_RETRIES
Err
Code Style
Names are the stratigraphy of your codebase. Run your eye down a file and you should read its history—what came from where, what belongs to what, what relates to what.
Naming Conventions
General Rules:
snake_casefor functions, variables, modulesPascalCasefor types, traits, enumsSCREAMING_SNAKE_CASEfor constants- No abbreviations except:
id,idx,len,ctx
Domain-Specific Names:
// IDs are always suffixed — the type tells you what you're holding
tenant_id: TenantId
record_id: RecordId
stream_id: StreamId
// Indexes are always suffixed
applied_idx: AppliedIndex
commit_idx: CommitIndex
// Offsets are explicit about what they offset
byte_offset: ByteOffset
log_offset: LogOffset
Verb Conventions:
// Constructors
// Borrowed view, no allocation
Function Structure
70-Line Soft Limit: If a function exceeds 70 lines, it probably does too much. This isn’t a hard rule—it’s a warning.
Main Logic First:
Early Returns for Guard Clauses:
Module Organization
crate_name/
├── lib.rs # Public API, re-exports
├── types.rs # Core types (or types/)
├── error.rs # Error types
├── traits.rs # Public traits
├── internal/ # Private implementation
│ ├── mod.rs
│ ├── parser.rs
│ └── writer.rs
└── tests/ # Integration tests
└── integration.rs
Production Assertion Strategy
Assertions are executable documentation of invariants. They detect corruption, Byzantine attacks, and state machine bugs before they propagate.
The Decision Matrix:
Use assert!() (production enforcement) for:
- Cryptographic invariants: All-zero detection, key hierarchy integrity
- Consensus safety: View/commit monotonicity, quorum validation, leader-only operations
- State machine correctness: Stream existence, offset monotonicity, effect completeness
- Compliance-critical: Tenant isolation (HIPAA/GDPR), audit trail integrity
Use debug_assert!() (development only) for:
- Performance-critical hot paths (after profiling confirms overhead)
- Redundant checks (type system already prevents error)
- Internal helper invariants (after production checks pass)
Never use assertions for:
- Input validation (use
Resulttypes) - Control flow (use
if/elseormatch) - Expected errors (use error handling)
Example Production Assertions:
// Cryptographic safety
assert!;
// Consensus safety
assert!;
// Tenant isolation (compliance-critical)
assert!;
Assertion Density Goal: Every function should have 2+ assertions (precondition + postcondition).
Testing: Every production assertion needs a #[should_panic] test:
Performance: 38 promoted production assertions added <0.1% throughput regression and +1μs p99 latency. Assertions are cold branches (predicted not-taken) with negligible overhead.
See docs/ASSERTIONS.md for complete guide with all 38 promoted assertions documented.
Error Handling
Errors are not failures. Errors are information. The only true failure is an error that goes unrecorded—a flaw that propagates without triggering a sensor.
Error Types
Use thiserror for library errors (specific, typed), anyhow for application errors (convenient, contextual):
// Library code: Specific error types with full context
use Error;
// Application code: Anyhow for convenient context chaining
use ;
No Unwrap in Library Code
// BAD: Panic on error — silent fracture
// GOOD: Propagate error — information preserved
Expect Over Unwrap for True Invariants
When unwrap is justified (states that are truly impossible if the code is correct), use expect with a reason. The reason is documentation—both for future readers and for the panic message if you were wrong.
// BAD: No context for impossible panic
let first = items.first.unwrap;
// GOOD: Documents why this can't fail
let first = items.first.expect;
Dependency Policy
Every dependency is a foreign formation attached to your crystal. It may be stable, or it may introduce flaws you can’t see. Question whether it belongs.
Tier 1: Trusted Core
Well-audited, stable, load-bearing. Always acceptable:
std(Rust standard library)serde,serde_json(serialization)thiserror,anyhow(errors)tracing(logging/observability)bytes(byte manipulation)
Tier 2: Carefully Evaluated
Use when necessary, evaluate each version:
mio(async I/O primitives)tokio(async runtime—minimize features)sqlparser(SQL parsing)proptest(property testing)
Tier 3: Cryptography
Never roll our own. Use well-audited crates only:
sha2(SHA-256, FIPS 180-4)ed25519-dalek(signatures, FIPS 186-5)aes-gcm(AES-256-GCM, FIPS 197)getrandom(OS CSPRNG, SP 800-90A/B)
Dependency Checklist
Before adding any dependency:
- Necessity: Can we implement this in under 200 lines?
- Quality: Is it maintained? Last commit? Issue response time?
- Security: Has it been audited? Any CVEs?
- Size: Impact on compile time and binary size?
- Stability: Stable API? Does it follow semver?
- Transitive deps: What does it pull in?
# Document why each dependency exists
[dependencies]
# Core serialization — stable, well-audited, used everywhere
serde = { version = "1", features = ["derive"] }
# Error handling for library code — zero cost, standard practice
thiserror = "2"
# Structured logging — async-safe, widely adopted
tracing = "0.1"
The Deep Time Perspective
“Audit trails are strata.”
Run your finger down a cliff face and you’re reading history. Every layer tells what happened, when, and in what order. If it’s not in the rock, it wasn’t deposited. If it’s not in the log, it didn’t happen.
Kimberlite is built for industries where code outlasts careers. The engineer who wrote a function may have left the company years ago. The regulator reading the audit trail has never seen your codebase. The security researcher examining a breach has only the evidence you left behind.
Write code with the patience of deep time:
- Make it compile-time over runtime — let the type system carry proofs
- Make it explicit over implicit — no hidden control flow, no magic
- Make it boring over clever — obvious code survives; clever code erodes
- Make it traceable over convenient — if it’s not logged, it didn’t happen
Clever code is tectonic drift—imperceptible motion that ends in earthquakes. You won’t notice the problem until the audit, the breach, the lawsuit. By then, the original author is gone and you’re reading code that seemed reasonable at the time.
Closing
“In the depth of winter, I finally learned that within me there lay an invincible summer.” — Albert Camus
Diamonds survive not through resistance, but through structural perfection. They have no flaws to exploit, no hidden weaknesses to fracture under pressure. They don’t fight the forces around them—they simply have nothing for them to break.
Write code with the same property.
Write code that will still be correct when the auditor arrives. Write code that will still be readable when you’ve moved on. Write code with the patience of deep time—because in regulated industries, someone will be reading it in ten years, and they will thank you or curse you based on what you write today.
Be the diamond.