From 2b8afd54e0550f9651e5ffc3d2b248a643e811bd Mon Sep 17 00:00:00 2001
From: Sunil Thakares
Date: Fri, 29 May 2026 21:25:23 +0530
Subject: [PATCH] docs: update README and docs for v0.6.0 architecture and
deployment, preserve current server/shared/wasm updates
---
.gitignore | 2 +
Cargo.lock | 12 +
README.md | 753 +++++----------------------------
docs/API.md | 237 +++++------
docs/ARCHITECTURE.md | 597 +++++---------------------
docs/DEPLOYMENT.md | 352 +++++----------
docs/DESIGN-PHILOSOPHY.md | 71 ++--
docs/PRIVACY POLICY.md | 292 ++-----------
docs/REFRACTORING-v0.6.0.md | 181 ++++----
docs/THREAT_MODEL.md | 246 ++++-------
docs/WASM_BUILD.md | 308 +++-----------
server/Cargo.toml | 1 +
server/src/cleanup.rs | 12 +-
server/src/cli.rs | 4 +
server/src/config.rs | 26 ++
server/src/errors.rs | 6 +
server/src/routes/heartbeat.rs | 28 +-
server/src/routes/init.rs | 3 +-
server/src/runtime.rs | 49 +--
server/src/session.rs | 261 +++++-------
server/src/storage.rs | 303 ++++++++++++-
shared/Cargo.toml | 1 +
shared/src/constants.rs | 6 +
shared/src/gene.rs | 13 +
shared/src/vm_extensions.rs | 149 ++++++-
wasm/Cargo.toml | 1 +
wasm/src/vm_extensions.rs | 66 +--
27 files changed, 1413 insertions(+), 2567 deletions(-)
diff --git a/.gitignore b/.gitignore
index b00867a..0b36a75 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,3 +5,5 @@ dist/
*.log
.env
.idea/
+
+.antigravitycli/
diff --git a/Cargo.lock b/Cargo.lock
index 6f34e89..05a4919 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -269,6 +269,7 @@ dependencies = [
"tracing",
"tracing-appender",
"tracing-subscriber",
+ "valkey",
]
[[package]]
@@ -285,6 +286,7 @@ dependencies = [
"serde-wasm-bindgen",
"serde_json",
"shared",
+ "tracing",
"wasm-bindgen",
]
@@ -1303,6 +1305,7 @@ dependencies = [
"rand 0.8.6",
"serde",
"serde_json",
+ "tracing",
]
[[package]]
@@ -1749,6 +1752,15 @@ dependencies = [
"wasm-bindgen",
]
+[[package]]
+name = "valkey"
+version = "0.0.0-alpha5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "591043068c3f8db7fc1dcf34852eb03994175d39045cf01ad036c099f3c4f888"
+dependencies = [
+ "tracing",
+]
+
[[package]]
name = "valuable"
version = "0.1.1"
diff --git a/README.md b/README.md
index 56f8301..e1eddbb 100644
--- a/README.md
+++ b/README.md
@@ -5,11 +5,11 @@
- Cryptographic attestation daemon and anti-automation framework.
+ Unix-native cryptographic attestation daemon for browser session continuity.
- Privacy-preserving • Unix-native • Lightweight • WASM-powered
+ Privacy-first • Deterministic WASM parity • Silent rejection • Low overhead
@@ -27,82 +27,69 @@
---
-ChronoSeal is a lightweight cryptographic attestation daemon designed to raise the operational cost of browser automation, scraping, replay attacks, and synthetic interaction.
+ChronoSeal is a mature Unix-native cryptographic attestation daemon for browser session continuity and anti-automation defense.
-Instead of relying on:
+It provides a low-overhead, privacy-respecting proof-of-runtime system built around a deterministic **Synthetic Gene Mutation Engine** and a silent, replay-resistant heartbeat protocol.
-* CAPTCHA systems
-* invasive browser fingerprinting
-* telemetry-heavy tracking
-* persistent identifiers
+v0.6.0 introduces the core innovation: a deterministic synthetic gene mutation chain with server/WASM parity, stronger liveness guarantees, and a domain-separated mutation commitment handshake.
-ChronoSeal establishes a continuous cryptographic proof-of-runtime continuity using:
+---
-* WASM execution
-* chained cryptographic heartbeats
+## What ChronoSeal Provides
+
+* Native Linux daemon with hardened `systemd` integration
+* Deterministic mutation engine running in both server Rust and client WASM
+* Silent rejection semantics for attacker resilience
+* Multi-backend storage: `sqlite-in-memory`, `sqlite-disk`, and `valkey`
+* CLI-first operation with rich subcommands
+* Structured logging, PID file management, graceful shutdown
+* Prometheus-compatible metrics and runtime statistics
+* Lightweight browser runtime with WASM-based attestation
+* Privacy-first design with ephemeral session state and no persistent tracking
+
+---
+
+## Why ChronoSeal
+
+ChronoSeal raises the operational cost of automation by combining:
+
+* cryptographic session continuity
+* deterministic VM execution
* behavioral entropy validation
-* ephemeral attestation state
+* mutation commitment parity
+* silent, ambiguous rejection behavior
-while remaining completely invisible and frictionless to legitimate human users.
-
-v0.6.0 adds a deterministic synthetic gene mutation chain (hybrid `Vec` gene + bounded environment records) to strengthen anti-replay continuity with server/WASM parity.
-See [docs/REFRACTORING-v0.6.0.md](docs/REFRACTORING-v0.6.0.md) for the full refactoring details.
+This is not a fingerprinting or surveillance platform. ChronoSeal is designed to make automation expensive, not to collect user identities.
---
-# Features
+## Quick Start
-* CLI-first Unix-native architecture
-* Rich operational subcommands
-* Machine-readable JSON/YAML outputs
-* Hardened systemd integration
-* Graceful shutdown and signal handling
-* One-line installation workflow
-* Prometheus-compatible metrics
-* WASM-based client runtime
-* Ed25519 + Blake3 cryptographic chaining
-* Behavioral entropy validation
-* Randomized stack-machine verification
-* Deterministic synthetic gene mutation chain
-* Server/WASM mutation parity checks
-* Silent rejection model
-* SQLite-backed ephemeral sessions
-* Configurable runtime DB backend selection (`db_type`)
-* Connection-pooled runtime architecture
-* Lightweight deployment footprint
-* Docker and native deployment support
-* Adaptive trust scoring
-* GPLv3 licensed
-
----
-
-# Quick Start
-
-## Install
+### Install
```bash
sudo bash scripts/install.sh
```
-## Check Status
+### Verify status
```bash
chronoseal status --format json
```
-## Health Probe
+### Health probe
```bash
chronoseal health
```
-## View Metrics
+### View metrics
```bash
chronoseal metrics
```
-## View Logs
+### Follow logs
```bash
sudo journalctl -u chronoseal -f
@@ -110,13 +97,13 @@ sudo journalctl -u chronoseal -f
---
-# CLI
+## CLI Overview
```bash
chronoseal --help
```
-## Available Commands
+### Available commands
| Command | Description |
| ------------ | ------------------------------------------ |
@@ -151,635 +138,89 @@ chronoseal status --format json
---
-# How It Works
+## Architecture Summary
-ChronoSeal establishes a continuous cryptographic proof-of-presence for browser sessions.
+ChronoSeal is composed of three primary runtime components:
-The system is inspired by heartbeat validation models used in embedded and distributed systems.
+* `shared/` — shared cryptographic primitives, hash chaining, gene model, and mutation engine used by both server and WASM
+* `server/` — Axum-based Unix-native daemon, session lifecycle, storage, trust evaluation, and `POST /init` / `POST /hb` routes
+* `wasm/` — browser runtime for key generation, signature creation, VM execution, and mutation preview/commit lifecycle
-## Session Flow
+### Key innovations in v0.6.0
-```text
-Browser Server
- │ │
- │ WASM loads, generates Ed25519 keypair │
- │ Private key never leaves WASM memory │
- │ │
- ├──── POST /init { public_key } ──────────►│
- │◄─── { session_id, salt, opcodes_b64, H0, │
- │ mutation_step, mutation_order_b64 } ──┤
- │ │
- │ Every 12–25s (randomized): │
- │ ┌─ Collect behavioral entropy │
- │ ├─ Execute verification VM opcodes │
- │ ├─ Preview mutation commitment │
- │ ├─ Attach mutation_step + commitment │
- │ ├─ Advance Blake3 hash chain │
- │ └─ Sign payload using Ed25519 │
- │ │
- ├──── POST /hb { signed_payload } ────────►│
- │◄─── { status, next_salt, │
- │ next_mutation_step, │
- │ next_mutation_order_b64 } ────────────┤
- │ │
- │ Invalid sessions silently rejected │
- │ (`status=ok` without next_* fields) │
-```
-
-The server validates:
-
-* signature authenticity
-* heartbeat continuity
-* replay resistance
-* mutation step parity
-* mutation commitment parity
-* behavioral entropy
-* timestamp validity
-* fingerprint sanity
+* Synthetic Gene Mutation Engine with deterministic, shared opcode semantics
+* Server-side gene commitment validation on every heartbeat
+* `mutation_step` and `mutation_order_b64` handshake in init and heartbeat responses
+* `db_type` runtime backend selection with SQLite and Valkey support
---
-# Security Model
+## How ChronoSeal Works
-## What ChronoSeal Protects Against
+ChronoSeal establishes continuity by chaining signed heartbeats between client and server.
-| Threat | Mechanism |
-| ------------------------ | ------------------------------------- |
-| Replay attacks | Blake3 chained heartbeat continuity |
-| Signature forgery | Ed25519 keypair generated inside WASM |
-| Session cloning | Ephemeral session-bound keypairs |
-| Static scraping | Runtime participation requirements |
-| Naive browser automation | Behavioral continuity validation |
-| Timestamp replay | Drift-window enforcement |
-| Session flooding | Per-session rate limiting |
-| Mutation tampering | Server-side commitment parity checks |
+### Session flow
+
+1. Client loads the WASM runtime and generates an Ed25519 keypair in WASM memory.
+2. Client calls `POST /init` with the public key.
+3. Server creates an ephemeral session and returns a `session_id`, initial salt, VM program, and mutation order metadata.
+4. Client executes the VM program, collects browser entropy, previews the mutation commitment, signs the heartbeat payload, and sends `POST /hb`.
+5. Server verifies signature, hash chain continuity, behavioral sanity, mutation step parity, and gene commitment before returning the next salt and mutation order.
+
+### Silent failure model
+
+Invalid heartbeats are returned as `{"status":"ok"}` without mutation fields. This avoids giving attackers explicit feedback.
---
-## Silent Rejection Model
+## Storage Backends
-ChronoSeal intentionally avoids explicit rejection semantics.
+ChronoSeal supports multiple runtime storage backends configured via `db_type`:
-Invalid sessions may still receive:
-
-```json
-{ "status": "ok" }
-```
-
-This prevents:
-
-* oracle-style probing
-* protocol learning
-* easy automation tuning
-* behavioral enumeration
+* `sqlite-in-memory` — default ephemeral session storage
+* `sqlite-disk` — persisted SQLite storage on disk
+* `valkey` — alternative backend compatibility mode for future high-performance storage
---
-## What ChronoSeal Does Not Claim
+## Deployment
-ChronoSeal is a cost-raising mechanism, not an impenetrable barrier.
+ChronoSeal is intended to run as a systemd-managed Unix daemon with strict sandboxing and observable metrics.
-A sufficiently motivated adversary with:
-
-* real browsers
-* genuine input devices
-* enough reverse engineering effort
-
-can eventually bypass the system.
-
-The goal is to make automation:
-
-* expensive
-* operationally complex
-* difficult to scale
-* harder to replay deterministically
+See [docs/DEPLOYMENT.md](docs/DEPLOYMENT.md) for build, installation, and production deployment guidance.
---
-# Architecture
+## Security Model
-```text
-chronoseal-rs/
-├── shared/ Shared types, hash chain, gene + mutation engine
-├── server/ Axum HTTP daemon
-│ ├── routes/ API routes
-│ ├── session.rs Session lifecycle + mutation parity checks
-│ ├── crypto.rs Ed25519 verification
-│ ├── trust.rs Behavioral validation
-│ ├── fingerprint/ Browser sanity validation
-│ ├── vm.rs Random opcode generator
-│ ├── ratelimit.rs Token bucket limiter
-│ ├── cleanup.rs Session expiration lifecycle
-│ └── metrics.rs Prometheus metrics
-├── wasm/ Rust → WASM runtime
-│ ├── crypto.rs Signing + hash chaining
-│ ├── vm.rs Stack-machine executor
-│ └── vm_extensions.rs Gene mutation preview/commit
-├── frontend/ Lightweight JS integration
-├── scripts/ Build/install/dev scripts
-└── docs/ Project documentation
-```
+ChronoSeal is a cost-raising attestations layer, not a perfect bot blocker.
+
+It protects against:
+
+* replay attacks
+* session cloning
+* invalid signature injection
+* broken hash chain continuity
+* mutation tampering
+* simple synthetic mouse and browser automation
+
+It does not attempt to protect against:
+
+* real users acting as bots
+* server-side application vulnerabilities
+* fully resourced adversaries with real browsers and hardware input devices
+
+See [docs/THREAT_MODEL.md](docs/THREAT_MODEL.md) for the full threat model.
---
-# Stack Machine
-
-ChronoSeal includes a lightweight randomized stack-machine execution engine.
-
-The server generates a randomized opcode program during session initialization.
-
-The client executes this program on every heartbeat and includes the resulting stack state in the signed payload.
-
-This makes heartbeat payloads structurally dynamic.
-
-## Supported Opcodes
-
-| Opcode | Mnemonic | Effect |
-| ------ | -------- | ----------------------- |
-| `0x00` | PUSH | Push literal |
-| `0x01` | ADD | Wrapping addition |
-| `0x02` | SUB | Wrapping subtraction |
-| `0x03` | MUL | Wrapping multiplication |
-| `0x04` | XOR | Bitwise XOR |
-| `0x05` | AND | Bitwise AND |
-| `0x06` | OR | Bitwise OR |
-| `0x07` | ROT | Rotate left |
-| `0x08` | NOT | Unary inversion |
-| `0x09` | HASH | Blake3 stack hash |
-
-## Mutation Opcodes (v0.6.0)
-
-| Opcode | Mnemonic | Effect |
-| ------ | -------------------- | ------ |
-| `0x23` | GENE_LOAD | Push `gene[idx]` |
-| `0x24` | GENE_STORE | Pop and store at `gene[idx]` |
-| `0x25` | MUTATE_POINT | Apply wrapping byte delta at index |
-| `0x26` | INSERT | Insert popped byte at index |
-| `0x27` | DELETE | Delete byte at index and push removed value |
-| `0x28` | TRANSCRIBE | Push deterministic transcription hash |
-| `0x29` | APPLY_MUTAGEN | Mix environment symbol quantity into gene byte |
-| `0x2A` | FINALIZE_GENE_HASH | Push commitment-derived `u32` |
-| `0x2B` | CONSUME | Pop amount, subtract environment quantity |
-| `0x2C` | PRODUCE | Pop amount, add environment quantity |
-
----
-
-# Hash Chain
-
-ChronoSeal uses Blake3 chained continuity validation.
-
-## Initial Hash
-
-```text
-H(0) = Blake3( session_id ║ public_key ║ salt₀ )
-```
-
-## Heartbeat Progression
-
-```text
-H(n) = Blake3(
- saltₙ₋₁ ║
- H(n-1) ║
- timestamp ║
- Blake3(entropy_json) ║
- Blake3(stack_json)
-)
-```
-
-Each heartbeat depends on:
-
-* prior continuity
-* prior server-issued salt
-* behavioral entropy
-* VM execution result
-* timestamp progression
-
----
-
-# Signature Canonicalization
-
-Heartbeat payloads are serialized into canonical key order before signing.
-
-The server reconstructs payloads identically before:
-
-* Ed25519 verification
-* hash progression validation
-
-This prevents:
-
-* serialization inconsistencies
-* ambiguous signing layouts
-* malformed payload tricks
-
----
-
-# SQLite Schema
-
-```sql
-CREATE TABLE IF NOT EXISTS sessions (
- session_id TEXT PRIMARY KEY,
- public_key BLOB NOT NULL,
- salt BLOB NOT NULL,
- last_hash BLOB NOT NULL,
- chain_length INTEGER NOT NULL DEFAULT 1,
- created_at INTEGER NOT NULL,
- last_seen INTEGER NOT NULL,
- expires_at INTEGER NOT NULL,
- gene BLOB NOT NULL DEFAULT X'',
- environment BLOB NOT NULL DEFAULT X'',
- pending_mutation BLOB NOT NULL DEFAULT X'',
- pending_mutation_step INTEGER NOT NULL DEFAULT 0
-);
-```
-
-ChronoSeal intentionally uses ephemeral session persistence.
-
-Session continuity is designed to reset transparently.
-
----
-
-# v0.6.0 — Synthetic Gene Mutation System
-
-## Overview & Motivation
-
-ChronoSeal v0.6.0 introduces a synthetic mutation chain model to strengthen attestation liveness and anti-replay guarantees while preserving privacy-first behavior. The core model combines:
-
-* a primary byte-oriented gene buffer (`Vec`), and
-* a bounded secondary environment map (`Vec<(u16 symbol, u32 quantity)>`).
-
-Each heartbeat now carries deterministic mutation progression evidence (`mutation_step`, `gene_commitment`) that is validated server-side against the exact server-issued mutation order. This design increases attacker workload by coupling cryptographic chain continuity with stateful deterministic mutation parity.
-
-## Architectural Goals
-
-1. Keep runtime behavior deterministic across server and WASM execution.
-2. Preserve ephemerality and low operational complexity.
-3. Minimize additional latency on the heartbeat path.
-4. Improve protocol resistance against replay and mutation tampering.
-5. Maintain a maintainable codebase with explicit invariants and focused modules.
-
-## Design Decisions
-
-**Shared mutation engine** — Mutation opcode semantics live in `shared/src/vm_extensions.rs` to guarantee server/client parity from one implementation.
-
-**Deterministic gene commitment** — A domain-separated BLAKE3 commitment (`chronoseal/gene/v1`) binds both gene bytes and sorted environment records.
-
-**Bounded mutation complexity** — Mutation program length is capped (`MAX_MUTATION_PROGRAM_BYTES`) and environment cardinality is capped (`MAX_ENV_RECORDS`).
-
-**Strict validation on ingest** — Environment payloads are validated for sortedness, uniqueness, non-zero quantity, and length constraints.
-
-**Protocol-level mutation handshake** — `InitResponse` and `Heartbeat` payloads now include mutation step/order and commitment fields.
-
-**DB backend control via `db_type`** — Server CLI/config now supports:
-
-* `sqlite-in-memory` (default)
-* `sqlite-in-disk` (active; uses `db_path`)
-* `valkey` (active compatibility mode; currently falls back to in-memory)
-
-## Implementation
-
-1. Gene model + deterministic commitment in `shared/gene.rs`.
-2. v0.6.0 mutation opcode set in shared VM extensions.
-3. Mutation state persisted per session (`gene`, `environment`, `pending_mutation`, `pending_mutation_step`).
-4. Protocol schema extended for mutation fields in init/heartbeat exchange.
-5. Mutation step + commitment parity validated before accepting heartbeat updates.
-6. WASM preview/commit mutation lifecycle mirrors server behavior.
-7. `db_type` CLI/config flow and runtime backend initialization strategy.
-8. Migration-safe schema extension (column existence checks + index creation).
-
-## Testing Strategy
-
-ChronoSeal v0.6.0 test coverage is organized across unit, integration, and randomized/fuzz-style validation.
-
-**Unit, integration, and property tests:**
-
-* Unit tests for gene invariants and encoding/decoding.
-* Unit tests for every mutation opcode with stack-effect assertions.
-* Integration tests for full session lifecycle and heartbeat acceptance/rejection paths.
-* Table-driven randomized tests and fuzz-style random bytecode tests to validate deterministic failure/success symmetry.
-
-**Server-client parity testing:**
-
-* Shared opcode engine parity tests across seeded mutation sequences.
-* Multi-step mutation chain test (`test_mutation_chain`) asserting identical server/client final state.
-* 10+ heartbeat deterministic simulation tests in session integration suite.
-
-**Evasion / attack simulation testing:**
-
-* Replay attack simulation.
-* Mutation step mismatch rejection.
-* Mutation commitment tampering rejection.
-* Malformed server mutation payload rejection.
-* Stack underflow / unknown opcode / truncated program rejection.
-
-**Performance regression testing:**
-
-* Bounded execution checks through capped program size and bounded record counts.
-* Timing smoke regression test for mutation execution loops.
-* End-to-end heartbeat test coverage to detect behavior regressions on hot paths.
-
-## Security Analysis
-
-**Replay resistance** — Heartbeats are now tied to both chain hash and mutation step progression.
-
-**Mutation tampering resistance** — Server recomputes candidate gene state from authoritative pending mutation program and rejects commitment mismatch.
-
-**Protocol ambiguity reduction** — Canonical signing payload includes mutation fields, reducing exploitable unsigned state.
-
-**Input hardening** — Program size limits, stack underflow checks, and strict environment decoding reduce parser abuse and malformed payload amplification.
-
-**Deterministic failure semantics** — Invalid mutation instructions fail predictably and symmetrically across server and WASM paths.
-
-## Performance Considerations
-
-* Mutation instructions are lightweight and mostly O(1); only `INSERT`/`DELETE` are O(n) but bounded by max gene size.
-* Environment operations use sorted-vector binary search with tight upper bound (`MAX_ENV_RECORDS`).
-* Commitment hashing is linear in gene size and record count, both bounded.
-* Shared engine avoids duplicate logic and divergence-induced debugging overhead.
-
-## Migration & Backward Compatibility
-
-* Schema migration is additive; new columns are created when missing.
-* Existing deployments without mutation fields require updated client+server pair for heartbeat compatibility.
-* `db_type` defaults to in-memory to preserve ephemeral behavior.
-* `sqlite-in-disk` is now directly usable via `db_path`.
-* `valkey` currently runs in compatibility mode (in-memory fallback) to avoid startup failure while preserving CLI contract.
-
-## Risks & Mitigations
-
-| Risk | Mitigation |
-| ---- | ---------- |
-| State divergence between server and client | Shared opcode engine + deterministic seeded parity tests + multi-heartbeat integration tests |
-| Mutation opcode abuse via malformed programs | Strict parsing, length caps, explicit underflow/unknown-opcode errors |
-| Performance regressions | Bounded structures, smoke timing tests, focused hot-path validation |
-| Backend confusion during `db_type` rollout | Explicit CLI command (`chronoseal db-type`), config output visibility, and clear runtime compatibility behavior |
-
----
-
-# Runtime Architecture
-
-## Server Runtime
-
-* Rust
-* Axum
-* Tokio
-* SQLite (`sqlite-in-memory` / `sqlite-in-disk`)
-* `db_type=valkey` compatibility mode (falls back to in-memory in v0.6.0)
-* `r2d2`
-* `thiserror`
-
-## Browser Runtime
-
-* Rust → WASM
-* Ed25519 signing
-* Blake3 chaining
-* Stack-machine execution
-
----
-
-# Deployment
-
-## Recommended Installation
-
-```bash
-sudo bash scripts/install.sh
-```
-
-The installer:
-
-* creates `chronoseal` service user
-* builds release artifacts
-* installs frontend assets
-* deploys hardened systemd service
-* enables and starts daemon
-
----
-
-## Manual Installation
-
-```bash
-bash scripts/build.sh
-
-sudo cp target/release/chronoseal /usr/local/bin/
-sudo cp chronoseal.service /etc/systemd/system/
-
-sudo systemctl daemon-reload
-sudo systemctl enable --now chronoseal
-```
-
----
-
-## Docker
-
-```bash
-docker compose up -d --build
-```
-
----
-
-# Development
-
-## Full Build
-
-```bash
-bash scripts/build.sh
-```
-
-## Development Mode
-
-```bash
-bash scripts/dev.sh
-```
-
-## Direct Execution
-
-```bash
-cargo run -p server -- run --bind 127.0.0.1:3000
-```
-
----
-
-# Prerequisites
-
-* Rust stable ≥ 1.87
-* `wasm-pack`
-* NodeJS (optional frontend tooling)
-
-Install `wasm-pack`:
-
-```bash
-cargo install wasm-pack
-```
-
-Build backend:
-
-```bash
-cargo run -p server --release
-```
-
-Build WASM:
-
-```bash
-wasm-pack build wasm --target web --release
-```
-
----
-
-# Configuration
-
-## Precedence
-
-```text
-CLI flags > CHRONOSEAL_* environment variables > config file > defaults
-```
-
-## Default Config Locations
-
-```text
-/etc/chronoseal/config.toml
-$XDG_CONFIG_HOME/chronoseal/config.toml
-~/.config/chronoseal/config.toml
-```
-
-## Runtime State
-
-```text
-~/.local/state/chronoseal/
-```
-
-## Database Backend Selection (v0.6.0)
-
-Choose backend with config, env var, or CLI flag:
-
-* Config: `db_type = "sqlite-in-memory" | "sqlite-in-disk" | "valkey"`
-* Env: `CHRONOSEAL_DB_TYPE=...`
-* CLI: `chronoseal run --db-type sqlite-in-disk --db-path /var/lib/chronoseal/chronoseal.sqlite`
-
-Inspect backend status:
-
-```bash
-chronoseal db-type --format text
-```
-
----
-
-# Observability
-
-ChronoSeal exposes:
-
-* health probes
-* runtime statistics
-* Prometheus metrics
-
-## Metrics Example
-
-```bash
-chronoseal metrics
-```
-
-```text
-# HELP chronoseal_sessions Active ChronoSeal sessions
-# TYPE chronoseal_sessions gauge
-chronoseal_sessions 1
-```
-
----
-
-# Lightweight Runtime
-
-Current release artifacts:
-
-```text
-chronoseal ~8.5 MB
-chronoseal_wasm.wasm ~719 KB
-```
-
-ChronoSeal intentionally avoids:
-
-* heavyweight frontend frameworks
-* Electron-style packaging
-* telemetry-heavy dependencies
-* oversized runtime models
-
----
-
-# Philosophy
-
-ChronoSeal is intentionally not:
-
-* a surveillance framework
-* invasive browser fingerprinting
-* a CAPTCHA replacement
-* a telemetry ecosystem
-
-ChronoSeal is:
-
-* a cryptographic attestation runtime
-* a behavioral continuity engine
-* a proof-of-runtime framework
-* a lightweight Unix-native daemon
-
----
-
-# Contributing
-
-## Requirements
-
-* Rust stable
-* wasm-pack
-* NodeJS (optional frontend tooling)
-
-## Development Workflow
-
-```bash
-cargo fmt
-cargo clippy
-cargo test
-```
-
-## Guidelines
-
-* Keep security-sensitive logic inside Rust/WASM
-* Avoid placing trust logic in JavaScript
-* Preserve silent-failure behavior
-* Maintain deterministic protocol serialization
-
----
-
-# Security Policy
-
-## Reporting Vulnerabilities
-
-Please do not disclose security vulnerabilities publicly before responsible disclosure.
-
-Contact maintainers privately with:
-
-* reproduction steps
-* affected versions
-* impact assessment
-* proof-of-concept if applicable
-
-## Scope
-
-ChronoSeal intentionally operates as:
-
-* anti-automation middleware
-* behavioral attestation layer
-* cryptographic continuity verifier
-
-Security hardening evolves continuously.
-
----
-
-# Language Breakdown
-
-| Language | Share |
-| ---------- | ------ |
-| Rust | 82.4% |
-| JavaScript | 13.7% |
-| Shell | 1.6% |
-| Dockerfile | 1.4% |
-| HTML | 0.9% |
-
----
-
-Topics: `rust` · `cryptography` · `wasm` · `antibot` · `browser-security` · `behavioral-analysis` · `anti-scraping` · `headless-detection`
+## Further Reading
+
+* [Architecture](docs/ARCHITECTURE.md)
+* [API Reference](docs/API.md)
+* [Deployment](docs/DEPLOYMENT.md)
+* [Threat Model](docs/THREAT_MODEL.md)
+* [Design Philosophy](docs/DESIGN-PHILOSOPHY.md)
+* [Privacy Policy](docs/PRIVACY%20POLICY.md)
+* [WASM Build](docs/WASM_BUILD.md)
+* [Refactoring v0.6.0](docs/REFRACTORING-v0.6.0.md)
diff --git a/docs/API.md b/docs/API.md
index 47db061..5bdebbb 100644
--- a/docs/API.md
+++ b/docs/API.md
@@ -1,20 +1,18 @@
-# ChronoSeal — API Reference
+# ChronoSeal API Reference
+
+ChronoSeal defines a small, deterministic API surface for browser attestation and heartbeat verification.
## Base URL
-All endpoints are relative to the server root. In development: `http://localhost:3000`.
-In production: your HTTPS domain via reverse proxy.
+All endpoints are relative to the server root. In development: `http://localhost:3000`. In production: the HTTPS origin of the protected site.
---
-## Endpoints
+## POST /init
-### `POST /init`
+Initialise a new browser session.
-Initialise a new session. Called once per page load, immediately after the
-WASM module generates an Ed25519 keypair.
-
-#### Request
+### Request
```http
POST /init
@@ -29,17 +27,17 @@ Content-Type: application/json
| Field | Type | Description |
|---|---|---|
-| `public_key` | `string` | Hex-encoded 32-byte Ed25519 verifying key generated by the WASM module |
+| `public_key` | `string` | Hex-encoded 32-byte Ed25519 public key generated by the WASM runtime |
-#### Response `200 OK`
+### Response `200 OK`
```json
{
- "session_id": "64-char hex string (32 bytes)",
- "salt": "32-char hex string (16 bytes)",
- "opcodes_b64": "base64-encoded VM program (8–16 opcodes)",
- "initial_hash": "64-char hex string (32 bytes Blake3)",
- "expires_at": 1234567890123,
+ "session_id": "64-char hex string",
+ "salt": "32-char hex string",
+ "opcodes_b64": "base64-encoded VM program",
+ "initial_hash": "64-char hex string",
+ "expires_at": 1234567890123,
"heartbeat_min_interval_ms": 12000,
"heartbeat_max_interval_ms": 25000,
"gene_size": 512,
@@ -50,29 +48,28 @@ Content-Type: application/json
| Field | Type | Description |
|---|---|---|
-| `session_id` | `string` | Opaque session identifier; include in every heartbeat |
-| `salt` | `string` | Initial salt; used to compute `H(0)` and first `H(1)` |
-| `opcodes_b64` | `string` | Base64 VM program; execute with `run_program()` on every heartbeat |
-| `initial_hash` | `string` | `H(0) = Blake3(session_id ║ pub_key ║ salt)`; the first `prev_hash` |
-| `expires_at` | `number` | Unix timestamp in milliseconds; session expires after 30 minutes of inactivity |
-| `heartbeat_min_interval_ms` | `number` | Lower bound for randomized heartbeat scheduling |
-| `heartbeat_max_interval_ms` | `number` | Upper bound for randomized heartbeat scheduling |
-| `gene_size` | `number` | Initial synthetic gene size used by server and WASM (default 512) |
-| `mutation_step` | `number` | Server-issued mutation order step expected on next heartbeat |
-| `mutation_order_b64` | `string` | Base64-encoded mutation opcode program for the current step |
+| `session_id` | `string` | Opaque session identifier for the current browser session |
+| `salt` | `string` | Random 16-byte salt used to seed the hash chain |
+| `opcodes_b64` | `string` | Base64-encoded randomized VM program executed on every heartbeat |
+| `initial_hash` | `string` | Initial chain hash `H(0)` used as `prev_hash` for the first heartbeat |
+| `expires_at` | `number` | Unix timestamp in milliseconds after which the session expires |
+| `heartbeat_min_interval_ms` | `number` | Minimum heartbeat interval in milliseconds |
+| `heartbeat_max_interval_ms` | `number` | Maximum heartbeat interval in milliseconds |
+| `gene_size` | `number` | Size of the initial synthetic gene buffer |
+| `mutation_step` | `number` | Initial mutation step expected on the first heartbeat |
+| `mutation_order_b64` | `string` | Base64-encoded mutation order for gene commitment preview |
-#### Error
+### Error
-Returns `500 Internal Server Error` only on server-side failures (DB errors,
-invalid public key length). No meaningful error body is returned.
+`POST /init` returns `500 Internal Server Error` only for server-side failures such as invalid public key length or persistence errors. No detailed error information is exposed to callers.
---
-### `POST /hb`
+## POST /hb
-Submit a heartbeat. Called every 12–25 seconds with uniform random jitter.
+Submit a heartbeat to continue the session.
-#### Request
+### Request
```http
POST /hb
@@ -81,13 +78,12 @@ Content-Type: application/json
```json
{
- "session_id": "64-char hex",
- "prev_hash": "64-char hex",
- "timestamp": 1234567890123,
+ "session_id": "64-char hex",
+ "prev_hash": "64-char hex",
+ "timestamp": 1234567890123,
"entropy_data": {
"events": [
- { "x": 412.0, "y": 308.5, "t": 1234.567 },
- { "x": 415.2, "y": 310.1, "t": 1285.123 }
+ { "x": 412.0, "y": 308.5, "t": 1234.567 }
]
},
"stack_state": {
@@ -95,74 +91,73 @@ Content-Type: application/json
"ip": 42
},
"fingerprint": {
- "aspectRatio": "1.7777777778",
- "devicePixelRatio": "2",
+ "aspectRatio": "1.7777777778",
+ "devicePixelRatio": 2,
"hardwareConcurrency": 8
},
"mutation_step": 1,
- "gene_commitment": "64-char hex Blake3 commitment",
- "signature": "128-char hex Ed25519 signature"
+ "gene_commitment": "64-char hex",
+ "signature": "128-char hex"
}
```
| Field | Type | Description |
|---|---|---|
| `session_id` | `string` | Session ID from `/init` |
-| `prev_hash` | `string` | Hash chain head from previous heartbeat (or `initial_hash` for the first) |
-| `timestamp` | `number` | `Date.now()` in milliseconds; must be within ±30s of server time |
-| `entropy_data.events` | `array` | Mouse events since previous heartbeat; each has `x`, `y` (px), `t` (performance.now ms) |
-| `stack_state.stack` | `array` | `u32[]` result of executing the VM program |
-| `stack_state.ip` | `number` | Instruction pointer after execution |
-| `fingerprint.aspectRatio` | `string` | `(screen.width / screen.height).toFixed(10)` |
-| `fingerprint.devicePixelRatio` | `string` | `String(window.devicePixelRatio)` |
-| `fingerprint.hardwareConcurrency` | `number` | `navigator.hardwareConcurrency \|\| 1` |
-| `mutation_step` | `number` | Must match server-side pending mutation step |
-| `gene_commitment` | `string` | Commitment of the locally previewed candidate gene after applying `mutation_order_b64` |
+| `prev_hash` | `string` | Previous hash chain head (`initial_hash` on first heartbeat) |
+| `timestamp` | `number` | `Date.now()` in milliseconds |
+| `entropy_data.events` | `array` | Mouse event list since the previous heartbeat |
+| `stack_state.stack` | `array` | VM stack contents after program execution |
+| `stack_state.ip` | `number` | VM instruction pointer after execution |
+| `fingerprint.aspectRatio` | `string` | `screen.width / screen.height` to 10 decimal places |
+| `fingerprint.devicePixelRatio` | `number` | `window.devicePixelRatio` |
+| `fingerprint.hardwareConcurrency` | `number` | `navigator.hardwareConcurrency || 1` |
+| `mutation_step` | `number` | Current mutation step sent by the client |
+| `gene_commitment` | `string` | Gene commitment produced by the WASM preview mutation engine |
| `signature` | `string` | Hex-encoded 64-byte Ed25519 signature over the canonical payload |
-#### Canonical Signing Payload
+### Canonical Signing Payload
-The client signs the following JSON object. Top-level keys must be sorted
-alphabetically. Nested object keys follow their natural serialisation order.
+The client signs a canonical JSON object with top-level keys sorted alphabetically:
```json
{
- "entropyData": { "events": [{ "t": …, "x": …, "y": … }] },
- "fingerprint": { "aspectRatio": "…", "devicePixelRatio": "…", "hardwareConcurrency": … },
- "geneCommitment":"…",
- "mutationStep": …,
- "prevHash": "…",
- "sessionId": "…",
- "stackState": { "ip": …, "stack": […] },
- "timestamp": …
+ "entropyData": { "events": [{ "t": ..., "x": ..., "y": ... }] },
+ "fingerprint": {
+ "aspectRatio": "...",
+ "devicePixelRatio": ...,
+ "hardwareConcurrency": ...
+ },
+ "geneCommitment": "...",
+ "mutationStep": ...,
+ "prevHash": "...",
+ "sessionId": "...",
+ "stackState": { "ip": ..., "stack": [...] },
+ "timestamp": ...
}
```
-Note: field names in the signing payload use camelCase (`sessionId`,
-`prevHash`, `entropyData`, `stackState`, `mutationStep`, `geneCommitment`)
-while the request body uses snake_case (`session_id`, `prev_hash`,
-`entropy_data`, `stack_state`, `mutation_step`, `gene_commitment`).
+Note: the signed payload uses camelCase while the transport request uses snake_case.
-#### Response `200 OK` — Accepted
+### Response `200 OK` — Accepted
```json
{
- "status": "ok",
- "next_salt": "32-char hex string (16 bytes)",
+ "status": "ok",
+ "next_salt": "32-char hex string",
"next_mutation_step": 2,
"next_mutation_order_b64": "base64-encoded mutation program"
}
```
-The client must:
-1. Preview commitment locally from `mutation_order_b64` and send it in the heartbeat.
-2. Capture `sentSalt = currentSalt` before updating.
-3. Set `currentSalt = next_salt`.
-4. Compute `prevHash = compute_next_hash(prevHash, timestamp, entropyJson, stackStateJson, sentSalt)`.
-5. Commit the previewed gene state.
-6. Replace pending mutation values with `next_mutation_step` and `next_mutation_order_b64`.
+| Field | Type | Description |
+|---|---|---|
+| `status` | `string` | Always `ok` |
+| `next_salt` | `string` | Next server salt for the following heartbeat |
+| `next_mutation_step` | `number` | Next mutation step to apply after acceptance |
+| `next_mutation_order_b64` | `string` | Base64-encoded next mutation program |
-#### Response `200 OK` — Rejected
+### Response `200 OK` — Rejected
```json
{
@@ -170,77 +165,45 @@ The client must:
}
```
-`next_salt`, `next_mutation_step`, and `next_mutation_order_b64` are absent.
-The response body is intentionally identical in
-structure. Rejections are silent — the caller cannot distinguish a validation
-failure from a rate limit hit or an expired session.
+A rejected heartbeat omits `next_salt`, `next_mutation_step`, and `next_mutation_order_b64`.
-The client should log a warning and continue scheduling heartbeats (they will
-continue to fail until the page is reloaded and a new session is established).
+This silent rejection model avoids giving attackers distinct failure signals.
---
-## Validation Rules (Server-Side)
+## Validation Rules
-Heartbeats are rejected (silently) if any of the following checks fail:
+Heartbeats are rejected silently when any validation step fails:
-| Check | Condition for rejection |
-|---|---|
-| Rate limit | > 5 requests per 10-second window for this `session_id` |
-| Session not found | `session_id` not in SQLite |
-| Session expired | `current_time_ms > expires_at` |
-| Signature invalid | Ed25519 verification fails against stored public key |
-| Hash chain broken | `hex(prev_hash) ≠ stored last_hash` |
-| Mutation step mismatch | `mutation_step ≠ pending_mutation_step` |
-| Mutation commitment mismatch | `gene_commitment` does not match server-computed candidate commitment |
-| Timestamp drift | `\|server_now_ms - timestamp\| > 30 000` |
-| Insufficient mouse events | `events.len() < 3` |
-| Insufficient mouse distance | `total_dist < 10.0 px` |
-| Mouse speed too high | `total_dist / total_time_ms > 2.0 px/ms` |
-| No mouse pauses | `pause_count < 1` |
-| Invalid aspect ratio | `ar < 0.5` or `ar > 3.0` |
-| Invalid devicePixelRatio | `dpr ≤ 0.0` or `dpr > 5.0` |
-| Zero hardwareConcurrency | `hardware_concurrency == 0` |
+* session missing or expired
+* signature invalid
+* hash chain mismatch
+* mutation step mismatch
+* gene commitment mismatch
+* timestamp outside ±30 seconds
+* insufficient mouse events
+* insufficient mouse movement
+* unrealistic speed profile
+* missing pause intervals
+* invalid fingerprint values
---
-## Hash Chain Specification
+## WASM Runtime Exports
-```
-H(0) = Blake3( session_id_bytes ║ pub_key_bytes ║ salt₀_bytes )
-
-H(n) = Blake3(
- saltₙ₋₁_bytes
- ║ H(n-1)_bytes
- ║ timestamp_u64_le_bytes
- ║ Blake3( UTF-8( JSON(entropy_data) ) )
- ║ Blake3( UTF-8( JSON(stack_state) ) )
-)
-```
-
-All inputs are concatenated in the order shown. `timestamp` is encoded as a
-64-bit unsigned integer in little-endian byte order. JSON serialisation of
-`entropy_data` and `stack_state` uses the field order defined by the shared
-Rust types (serde derive, no custom ordering).
-
----
-
-## WASM API
-
-The WASM module (`chronoseal_wasm`) exports the following functions to JavaScript:
+The WASM module exports the following functions to JavaScript:
| Function | Signature | Description |
|---|---|---|
-| `generate_keypair()` | `() → string` | Generate Ed25519 keypair; return hex public key. Private key stored in WASM memory. |
-| `get_public_key()` | `() → string` | Return hex public key, or `""` if not initialised. |
-| `sign_message(msg)` | `(string) → string` | Sign UTF-8 string; return hex signature, or `""` if not initialised. |
-| `compute_next_hash(prev, ts, entropy, stack, salt)` | `(string, u64, string, string, string) → string` | Compute next Blake3 chain hash; all inputs/output hex or JSON strings. |
-| `run_program(b64)` | `(string) → JsValue` | Execute base64 VM program; return `{ stack: u32[], ip: number }`. |
-| `init_gene_state(gene_size)` | `(u32) → bool` | Initialise synthetic gene state in WASM memory. |
-| `preview_gene_commitment(order_b64)` | `(string) → string` | Apply mutation order on preview state and return commitment hex. |
-| `commit_gene_preview()` | `() → bool` | Commit previewed mutation state after accepted heartbeat. |
-| `discard_gene_preview()` | `() → void` | Discard previewed mutation state after rejection/error. |
-| `current_gene_commitment()` | `() → string` | Return current committed gene commitment hex. |
+| `generate_keypair()` | `() -> string` | Generate a new Ed25519 keypair and return the public key hex |
+| `get_public_key()` | `() -> string` | Return the current public key hex |
+| `sign_message(msg)` | `(string) -> string` | Sign a UTF-8 string payload and return the hex signature |
+| `compute_next_hash(prev, ts, entropy, stack, salt)` | `(string, u64, string, string, string) -> string` | Compute the next Blake3 hash chain value |
+| `run_program(b64)` | `(string) -> JsValue` | Execute a base64 VM program and return stack state |
+| `init_gene_state(gene_size)` | `(u32) -> bool` | Initialise the synthetic gene buffer in WASM memory |
+| `preview_gene_commitment(order_b64)` | `(string) -> string` | Preview the next gene commitment from a mutation order |
+| `commit_gene_preview()` | `() -> bool` | Commit the previewed mutation after an accepted heartbeat |
+| `discard_gene_preview()` | `() -> void` | Discard the previewed mutation after rejection or error |
+| `current_gene_commitment()` | `() -> string` | Return the current committed gene commitment |
-String-returning functions return `""` on error rather than panicking. Callers
-must check for empty strings and boolean return values before use.
+String-returning functions return `""` on error. Callers must handle empty values and boolean failures gracefully.
diff --git a/docs/ARCHITECTURE.md b/docs/ARCHITECTURE.md
index e800487..2a03630 100644
--- a/docs/ARCHITECTURE.md
+++ b/docs/ARCHITECTURE.md
@@ -1,526 +1,145 @@
-# ChronoSeal — Architecture
+# ChronoSeal Architecture
-> Note (v0.6.0): Synthetic Gene Mutation flow and mutation handshake updates are documented in [REFRACTORING-v0.6.0.md](https://github.com/thakares/chronoseal-rs/blob/main/docs/REFRACTORING-v0.6.0.md) and [API.md](https://github.com/thakares/chronoseal-rs/blob/main/docs/API.md).
+ChronoSeal is a Unix-native cryptographic attestation daemon that validates browser session continuity through deterministic VM execution, chained cryptographic state, and a shared Synthetic Gene Mutation Engine.
## Overview
-ChronoSeal is a stateless, cryptographic browser attestation framework. Its
-purpose is to make automated clients (headless browsers, AI scrapers, API
-harvesters) computationally expensive and operationally complex to operate,
-while remaining completely invisible to real human users.
+ChronoSeal is designed as a production-grade infrastructure component, not as a consumer-facing widget. It is a lightweight daemon that can be operated, monitored, and integrated like any other native Linux service.
-The design is inspired by the heartbeat model used in embedded IoT firmware:
-a device that stops sending signed, chained attestations is assumed to be
-offline or compromised. ChronoSeal applies the same principle to browser
-sessions.
+Key characteristics:
----
+* Unix-native daemon with systemd-compatible lifecycle
+* CLI-first control plane and configuration
+* Shared Rust/WASM runtime for server/client parity
+* Modular storage backend abstraction (`sqlite-in-memory`, `sqlite-disk`, `valkey`)
+* Silent rejection semantics for attacker resilience
+* Privacy-preserving ephemeral session state
-## Design Principles
+## Core Components
-**Stateless per request.** The server carries no per-request state beyond what
-is stored in SQLite keyed on `session_id`. Every HTTP request is independently
-verifiable.
+### `shared/`
-**Silent failure.** Validation failures never return an error status or an
-error body. The server always responds `{"status":"ok"}` and simply omits `next_salt`. The client degrades gracefully. Attackers cannot enumerate
-validation rules by probing error responses.
+Shared protocol and runtime primitives used by both the server and the browser runtime:
-**Private key isolation.** The Ed25519 signing key is generated inside the
-WASM module and never serialised, never exposed to the JavaScript environment,
-and never transmitted. It exists only in WASM linear memory for the lifetime
-of the page.
+* Cryptographic primitives: Blake3, Ed25519
+* Hash chain logic and session commitment handling
+* Synthetic gene model and deterministic mutation engine
+* Serialization, encoding, and canonical signing helpers
-**Layered validation.** A heartbeat must pass five independent checks: session
-existence, expiry, signature, hash chain, and behavioral signals. Bypassing
-one layer is not sufficient.
+### `server/`
-**Cost asymmetry.** Each heartbeat requires a real browser environment, mouse
-activity, correct WASM execution, chain state synchronisation, and a valid
-Ed25519 signature over a time-windowed payload. For an automated client, the
-synchronisation burden alone makes scaled operation expensive.
+The server crate implements the runtime daemon:
-**Deterministic mutation parity (v0.6.0).** Each heartbeat additionally carries
-a `mutation_step` and `gene_commitment` derived from a server-issued mutation
-program. Server and WASM execute the same shared opcode engine
-(`shared/src/vm_extensions.rs`), and the server rejects any heartbeat where
-the recomputed commitment does not match the client-supplied value.
+* `routes/init.rs` — session initialization API
+* `routes/heartbeat.rs` — heartbeat verification API
+* `session.rs` — session lifecycle, mutation parity, and heartbeat validation
+* `storage.rs` — backend abstraction and persistence
+* `crypto.rs` — signature verification and key handling
+* `trust.rs` — behavioral entropy and sanity validation
+* `ratelimit.rs` — per-session request throttling
+* `cleanup.rs` — expiration and eviction tasks
+* `runtime.rs` — daemon bootstrap, metrics, and state management
-### High-Level Design
+### `wasm/`
-- **Core**: Rust + Axum (async web framework)
-- **Storage**: `db_type` selectable (`sqlite-in-memory`, `sqlite-in-disk`, `valkey` compatibility mode)
-- **Client**: WASM + Rust (runs in browser for proof generation)
-- **Security Model**: Behavioral analysis + hash chaining + entropy scoring + deterministic gene mutation parity
-- **Deployment**: Static musl binary, systemd service, optional Docker
+The client runtime crate compiles to WebAssembly and powers attestation in the browser.
-### Key Components
+* `crypto.rs` — in-WASM signing and hash computation
+* `vm.rs` — randomized opcode VM execution
+* `vm_extensions.rs` — synthetic gene mutation preview and commit lifecycle
-- `shared/` — Types, constants, crypto primitives, gene model, and mutation engine used by server and WASM
-- `server/` — Axum routes, session management, trust engine, rate limiting, cleanup tasks
-- `wasm/` — Client-side proof generation, mutation preview/commit lifecycle
-- `frontend/` — Static assets served by the application
+### `frontend/`
-### Unix-Native Design Decisions
+Static browser integration code that loads the WASM module, orchestrates init/heartbeat flow, and collects browser entropy.
-- Runs as a proper systemd service with strict sandboxing
-- All state is either in-memory or in standard locations (`/run/`, `/var/log/`, `/etc/`)
-- Graceful shutdown and reload support via signals
-- Logging designed for `journalctl` and structured parsing
-- Configuration is fully runtime (no recompile needed)
+## v0.6.0 Innovation
-### Design Goal
+The primary innovation in v0.6.0 is the **Synthetic Gene Mutation Engine**.
-## ChronoSeal should feel as natural to use as `nginx` or `redis-server` on a Linux system.
+This layer adds a deterministic, shared server/WASM mutation handshake to the existing heartbeat continuity model.
-## Component Map
+Key v0.6.0 behavior:
+
+* `mutation_order_b64` is issued at session initialization and after every accepted heartbeat
+* `mutation_step` is tracked on both client and server
+* `gene_commitment` is computed locally in WASM and validated by the server
+* mutation state is persisted per session and advanced only on accepted heartbeats
+* scalar mutation programs are deterministic and bounded in cost
+
+This makes replay and tampering attacks significantly more expensive while preserving the existing privacy-first and silent-failure semantics.
+
+## Architecture Diagram
```
-┌─────────────────────────────────────────────────────────┐
-│ Browser │
-│ │
-│ ┌─────────────┐ ┌──────────────┐ ┌─────────────┐ │
-│ │ entropy.js │ │ heartbeat.js │ │ transport.js│ │
-│ │ │ │ │ │ │ │
-│ │ mousemove │──►│ orchestrates │──►│ fetch POST │ │
-│ │ event ring │ │ init + HB │ │ /init /hb │ │
-│ └─────────────┘ └──────┬───────┘ └─────────────┘ │
-│ │ │
-│ ┌──────▼───────────────────────┐ │
-│ │ WASM Module (antibot_wasm) │ │
-│ │ │ │
-│ │ crypto.rs vm.rs │ │
-│ │ ├ generate_keypair() │ │
-│ │ ├ sign_message() │ │
-│ │ ├ compute_next_hash() │ │
-│ │ ├ run_program() │ │
-│ │ vm_extensions.rs │ │
-│ │ ├ preview_mutation() │ │
-│ │ └ commit_mutation() │ │
-│ └──────────────────────────────┘ │
-└─────────────────────────────────────────────────────────┘
- │ HTTPS
-┌─────────────────────────▼───────────────────────────────┐
-│ Server (Axum) │
-│ │
-│ routes/init.rs routes/heartbeat.rs │
-│ │ │ │
-│ └──────────┬───────────────┘ │
-│ ▼ │
-│ session.rs │
-│ ├ create_session() │
-│ └ verify_heartbeat() │
-│ └ validate_mutation_parity() [v0.6.0] │
-│ │ │
-│ ┌──────────┼──────────────┐ │
-│ ▼ ▼ ▼ │
-│ crypto.rs trust.rs fingerprint.rs │
-│ (sig verify) (mouse (aspect ratio, │
-│ speed) DPR, HW conc.) │
-│ │ │
-│ ▼ │
-│ shared::hashing (Blake3 hash chain) │
-│ shared::gene (gene model + commitment) [v0.6.0] │
-│ shared::vm_extensions (mutation opcodes) [v0.6.0] │
-│ │ │
-│ ▼ │
-│ storage.rs (SQLite: in-memory / in-disk / valkey) │
-│ │
-│ ratelimit.rs cleanup.rs vm.rs middleware.rs │
-└─────────────────────────────────────────────────────────┘
+Browser Server
+ ┌──────────────────────────────────────────────────────────────┐
+ │ frontend/ + WASM runtime │
+ │ - generate_keypair() │
+ │ - sign_message() │
+ │ - compute_next_hash() │
+ │ - run_program() │
+ │ - preview_gene_commitment() │
+ │ - commit_gene_preview() │
+ │ │
+ │ POST /init -> │
+ │ POST /hb -> │
+ └──────────────────────────────────────────────────────────────┘
+ │
+ ▼
+ ┌──────────────────────────────────────────────────────────────┐
+ │ server/ │
+ │ - signature validation │
+ │ - hash chain continuity │
+ │ - rate limiting │
+ │ - behavioral trust checks │
+ │ - mutation step validation │
+ │ - gene commitment verification │
+ │ - session persistence │
+ │ - metrics and health │
+ └──────────────────────────────────────────────────────────────┘
+ │
+ ▼
+ ┌──────────────────────────────────────────────────────────────┐
+ │ storage backends │
+ │ - sqlite-in-memory │
+ │ - sqlite-disk │
+ │ - valkey compatibility mode │
+ └──────────────────────────────────────────────────────────────┘
```
----
+## Storage Backends
-## Session Lifecycle
+ChronoSeal supports pluggable backend modes using the `db_type` configuration option.
-### 1. Initialisation — `POST /init`
+* `sqlite-in-memory` — default ephemeral session storage. No persistence across restarts.
+* `sqlite-disk` — persisted SQLite database on disk through `db_path`.
+* `valkey` — compatibility mode for alternative storage backends, currently supported alongside SQLite compatibility semantics.
-```
-Client Server
- │ │
- │ generate Ed25519 keypair (in WASM) │
- │ pub_key = verifying_key.to_bytes() │
- │ │
- ├─── { public_key: hex(pub_key) } ──────►│
- │ │ session_id = rand::random::<[u8;32]>()
- │ │ salt₀ = rand::random::<[u8;16]>()
- │ │ H(0) = Blake3(session_id║pub_key║salt₀)
- │ │ opcodes = generate_random_program(8..=16)
- │ │ gene = initial gene buffer [v0.6.0]
- │ │ mutation_order = generate_mutation_program() [v0.6.0]
- │ │ INSERT INTO sessions …
- │ │
- │◄── { session_id, salt, opcodes_b64, │
- │ initial_hash, expires_at, │
- │ mutation_step, │ [v0.6.0]
- │ mutation_order_b64 } ─────────────┤ [v0.6.0]
- │ │
- │ prevHash = initial_hash │
- │ currentSalt = salt │
- │ opcodesB64 = opcodes_b64 │
- │ mutationStep = mutation_step │ [v0.6.0]
- │ mutationOrderB64 = mutation_order_b64 │ [v0.6.0]
-```
+## Runtime Philosophy
-### 2. Heartbeat — `POST /hb`
+ChronoSeal is intentionally designed to behave like traditional Unix infrastructure software:
-Fired every 12–25 seconds with uniform random jitter.
+* explicit CLI operations (`run`, `status`, `health`, `config`, `metrics`, `stats`, `db-type`)
+* structured logging for `journalctl`
+* PID file management and graceful shutdown
+* systemd sandbox support
+* runtime configuration via TOML and CLI overrides
+* clear separation of protocol, persistence, and runtime concerns
-```
-Client Server
- │ │
- │ stackState = run_program(opcodesB64) │
- │ commitment = preview_mutation( │ [v0.6.0]
- │ mutationOrderB64, mutationStep) │
- │ events = collectEntropy(lastTime)│
- │ ts = Date.now() │
- │ │
- │ signable = { │
- │ entropyData, fingerprint, │ ← keys sorted alphabetically
- │ prevHash, sessionId, │
- │ stackState, timestamp, │
- │ mutation_step, gene_commitment │ [v0.6.0]
- │ } │
- │ sig = sign_message( │
- │ JSON.stringify(signable, keys.sort))│
- │ │
- ├─── { session_id, prev_hash, timestamp, │
- │ entropy_data, stack_state, │
- │ fingerprint, signature, │
- │ mutation_step, gene_commitment }─►│ [v0.6.0]
- │ │ 1. Rate limit check
- │ │ 2. Lookup session, check expiry
- │ │ 3. Verify Ed25519 signature
- │ │ 4. Verify hash chain continuity
- │ │ 5. Validate timestamp window ±30s
- │ │ 6. Validate mouse behavior
- │ │ 7. Validate fingerprint signals
- │ │ 8. Validate mutation step parity [v0.6.0]
- │ │ 9. Validate gene commitment [v0.6.0]
- │ │ 10. Compute H(n), rotate salt
- │ │ 11. Advance gene state [v0.6.0]
- │ │ 12. UPDATE sessions …
- │ │
- │◄── { status: "ok", next_salt, │
- │ next_mutation_step, │ [v0.6.0]
- │ next_mutation_order_b64 } ────────┤ [v0.6.0]
- │ │
- │ sentSalt = currentSalt ◄── captured BEFORE rotation
- │ currentSalt = next_salt │
- │ mutationStep = next_mutation_step │ [v0.6.0]
- │ mutationOrderB64 = next_mutation_order_b64 [v0.6.0]
- │ prevHash = compute_next_hash( │
- │ prevHash, ts, entropy, │
- │ stackState, sentSalt) │
-```
+## Integration Points
-### 3. Failure Path
+* Browser clients consume the WASM module and call `/init` and `/hb`
+* Existing sites can proxy these API routes through their own web server
+* Frontend assets can be served by ChronoSeal directly or mounted in a sidecar deployment
+* TLS termination should be handled by a reverse proxy in production
-On any validation failure the server returns `{"status":"ok"}` with no `next_salt`. The client logs a warning and continues scheduling heartbeats.
-The chain is broken — subsequent heartbeats will also fail silently.
-No error is surfaced to the page or its visitors.
+## Operating Assumptions
----
+ChronoSeal is not a general-purpose authentication service. It is a cryptographic attestation and anti-automation layer intended to be integrated with existing site logic.
-## Cryptographic Protocol
+It assumes:
-### Key Generation
-
-```
-Ed25519 keypair generated via ed25519-dalek + rand::thread_rng (OS-seeded)
-Private key: stored in WASM thread_local, never leaves WASM memory
-Public key: 32 bytes, hex-encoded, sent to server at init
-```
-
-### Hash Chain
-
-```
-H(0) = Blake3( session_id ║ pub_key ║ salt₀ )
-
-H(n) = Blake3(
- saltₙ₋₁ ← server-side only, rotated each heartbeat
- ║ H(n-1) ← must match stored last_hash
- ║ timestamp_u64_le
- ║ Blake3( JSON(entropy_data) )
- ║ Blake3( JSON(stack_state) )
-)
-```
-
-Salt rotation means an attacker who intercepts a heartbeat cannot compute
-future chain links without also intercepting every subsequent server response.
-
-### Gene Commitment (v0.6.0)
-
-A domain-separated BLAKE3 commitment binds both the gene buffer and the sorted
-environment records into a single 32-byte value that is included in the signed
-heartbeat payload and validated server-side:
-
-```
-gene_commitment = BLAKE3(
- "chronoseal/gene/v1" ← domain separator
- ║ gene_bytes ← Vec gene buffer
- ║ for each (symbol, qty) sorted by symbol:
- symbol_u16_le ║ qty_u32_le
-)
-```
-
-The server recomputes the candidate gene state from its authoritative
-`pending_mutation` program and rejects any heartbeat where
-`recomputed_commitment != client_gene_commitment`.
-
-### Canonical Signing Payload
-
-The signed message is a JSON object with top-level keys sorted alphabetically,
-serialised with no extra whitespace:
-
-```
-{
- "entropyData": { "events": [{"t":…,"x":…,"y":…}] },
- "fingerprint": { "aspectRatio":"…","devicePixelRatio":"…","hardwareConcurrency":… },
- "gene_commitment": "hex…",
- "mutation_step": N,
- "prevHash": "hex…",
- "sessionId": "hex…",
- "stackState": { "ip":…,"stack":[…] },
- "timestamp": 1234567890123
-}
-```
-
-The server reconstructs this using `std::collections::BTreeMap` (alphabetical
-key order) before calling `VerifyingKey::verify_strict`. Any field mismatch,
-key order difference, or whitespace difference causes a signature failure.
-
-### Hashing Algorithm
-
-Blake3 is used throughout: hash chain links, entropy data digest, stack state
-digest, gene commitment, and the VM HASH opcode. Blake3 is chosen for speed
-in WASM, resistance to length-extension attacks, and a clean Rust API.
-
----
-
-## Stack Machine
-
-The server generates a random program on session init. The client executes it
-on every heartbeat and includes the resulting `StackState { stack, ip }` in
-the signed payload. This ensures each heartbeat carries unique, verifiable
-computation without additional round-trips.
-
-### Core Instruction Set
-
-| Opcode | Mnemonic | Operand | Stack effect | Description |
-| ------ | -------- | ----------- | ------------ | -------------------------------------- |
-| `0x00` | PUSH | u32 (4B LE) | +1 | Push literal |
-| `0x01` | ADD | — | −1 | `a + b` wrapping |
-| `0x02` | SUB | — | −1 | `a - b` wrapping |
-| `0x03` | MUL | — | −1 | `a * b` wrapping |
-| `0x04` | XOR | — | −1 | `a ^ b` |
-| `0x05` | AND | — | −1 | `a & b` |
-| `0x06` | OR | — | −1 | `a \| b` |
-| `0x07` | ROT | — | −1 | `a.rotate_left(b % 32)` |
-| `0x08` | NOT | — | 0 | `!a` (unary) |
-| `0x09` | HASH | — | -(depth-1) | Blake3 of all stack items → single u32 |
-
-The generator ensures ≥ 2 items on the stack before any binary opcode.
-NOT (0x08) does not change depth. HASH resets depth to 1.
-
-### Mutation Opcodes (v0.6.0)
-
-The gene mutation extension operates on a separate `Vec` gene buffer and a
-bounded environment map `Vec<(u16 symbol, u32 quantity)>`. These opcodes are
-defined in `shared/src/vm_extensions.rs` and executed identically by both
-server and WASM to guarantee deterministic parity.
-
-| Opcode | Mnemonic | Effect |
-| ------ | ------------------ | ------------------------------------------------------------- |
-| `0x23` | GENE_LOAD | Push `gene[idx]` onto the stack |
-| `0x24` | GENE_STORE | Pop stack top and store at `gene[idx]` |
-| `0x25` | MUTATE_POINT | Apply wrapping byte delta at index |
-| `0x26` | INSERT | Insert popped byte at index |
-| `0x27` | DELETE | Delete byte at index and push the removed value |
-| `0x28` | TRANSCRIBE | Push deterministic transcription hash of current gene state |
-| `0x29` | APPLY_MUTAGEN | Mix environment symbol quantity into gene byte at index |
-| `0x2A` | FINALIZE_GENE_HASH | Push commitment-derived `u32` onto the stack |
-| `0x2B` | CONSUME | Pop amount, subtract from environment symbol quantity |
-| `0x2C` | PRODUCE | Pop amount, add to environment symbol quantity |
-
-**Constraints enforced at runtime:**
-
-- Mutation program length capped at `MAX_MUTATION_PROGRAM_BYTES`
-- Environment record count capped at `MAX_ENV_RECORDS`
-- Environment records validated for sortedness, uniqueness, non-zero quantity
-- Stack underflow and unknown opcodes cause deterministic, symmetric failures on both server and WASM paths
-
----
-
-## Behavioral Validation
-
-### Mouse Entropy
-
-Every heartbeat includes the mouse events collected since the previous
-heartbeat. Server checks:
-
-| Check | Threshold |
-| --------------------------- | ------------------------------------ |
-| Minimum event count | ≥ 3 |
-| Minimum cumulative distance | ≥ 10 px |
-| Maximum average speed | ≤ 2.0 px/ms (distance / elapsed ms) |
-| Minimum pause count | ≥ 1 (movement < 0.2 px over > 50 ms) |
-
-### Browser Fingerprint
-
-| Signal | Valid range |
-| ------------------------------ | ------------- |
-| `aspectRatio` (width / height) | 0.5 – 3.0 |
-| `devicePixelRatio` | 0 < dpr ≤ 5.0 |
-| `hardwareConcurrency` | ≥ 1 |
-
----
-
-## Rate Limiting
-
-Token bucket per `session_id`: 5 requests / 10-second window.
-Stale entries evicted every 60 seconds by the cleanup task.
-Rate-limited responses are indistinguishable from validation failures.
-
----
-
-## SQLite Schema
-
-The schema is extended in v0.6.0 with four new columns to persist per-session
-gene mutation state. Migration is additive — columns are created when missing,
-preserving compatibility with existing deployments.
-
-```sql
-CREATE TABLE IF NOT EXISTS sessions (
- session_id TEXT PRIMARY KEY,
- public_key BLOB NOT NULL, -- 32-byte Ed25519 verifying key
- salt BLOB NOT NULL, -- 16-byte current salt
- last_hash BLOB NOT NULL, -- 32-byte Blake3 chain head
- chain_length INTEGER NOT NULL DEFAULT 1,
- created_at INTEGER NOT NULL, -- Unix ms
- last_seen INTEGER NOT NULL, -- Unix ms
- expires_at INTEGER NOT NULL, -- Unix ms
- -- v0.6.0: gene mutation state
- gene BLOB NOT NULL DEFAULT X'', -- Vec gene buffer
- environment BLOB NOT NULL DEFAULT X'', -- Vec<(u16, u32)> env records
- pending_mutation BLOB NOT NULL DEFAULT X'', -- server-issued mutation program
- pending_mutation_step INTEGER NOT NULL DEFAULT 0 -- current mutation step counter
-);
-```
-
-In-memory SQLite (`sqlite-in-memory`) — all sessions lost on server restart by
-design. Clients re-initialise transparently on the next page load. Use
-`sqlite-in-disk` for persistent sessions across restarts.
-
----
-
-## Storage Backend (v0.6.0)
-
-ChronoSeal v0.6.0 introduces selectable database backends via the `db_type`
-configuration option. The default remains in-memory to preserve ephemeral
-session behavior.
-
-### Backend Options
-
-| `db_type` | Behavior |
-| ------------------ | -------------------------------------------------------------------- |
-| `sqlite-in-memory` | Default. All sessions ephemeral; lost on restart. Zero disk I/O. |
-| `sqlite-in-disk` | Persistent sessions. Requires `db_path`. Survives restarts. |
-| `valkey` | Compatibility mode. Currently falls back to in-memory. CLI contract preserved. |
-
-### Configuration
-
-**Config file** (`/etc/chronoseal/config.toml`):
-```toml
-db_type = "sqlite-in-disk"
-db_path = "/var/lib/chronoseal/chronoseal.sqlite"
-```
-
-**Environment variable**:
-```bash
-CHRONOSEAL_DB_TYPE=sqlite-in-disk
-CHRONOSEAL_DB_PATH=/var/lib/chronoseal/chronoseal.sqlite
-```
-
-**CLI flag**:
-```bash
-chronoseal run --db-type sqlite-in-disk --db-path /var/lib/chronoseal/chronoseal.sqlite
-```
-
-**Inspect active backend**:
-```bash
-chronoseal db-type --format text
-```
-
-### Precedence
-
-```
-CLI flags > CHRONOSEAL_* environment variables > config file > defaults
-```
-
-### Migration Notes
-
-- Schema migration is additive; new columns are created when missing on startup.
-- Switching from `sqlite-in-memory` to `sqlite-in-disk` requires no code changes — only config.
-- `valkey` is available in the CLI contract today; full backend support is tracked for a future release.
-- Existing deployments without the v0.6.0 mutation columns will have those columns added automatically on first start.
-
----
-
-## Threat Model
-
-### In Scope
-
-| Threat | Mitigation |
-| ------------------------------------------ | --------------------------------------------------------------- |
-| Playwright / Puppeteer / Selenium | Mouse entropy + behavioral validation |
-| Puppeteer Stealth, undetected-chromedriver | Signature over VM execution state |
-| Heartbeat replay | Hash chain + ±30s timestamp window |
-| Mutation replay | mutation_step + gene_commitment parity check (v0.6.0) |
-| Mutation tampering | Server recomputes candidate gene from authoritative program (v0.6.0) |
-| Signature forgery | Private key isolated in WASM memory |
-| Parallel session sharing | Each session bound to a unique keypair |
-| Brute-forced session IDs | 256-bit random entropy |
-| Flooding with fake session IDs | Rate limiter + periodic HashMap eviction |
-| Traffic analysis | Uniform `{"status":"ok"}` on all failure paths |
-| Malformed mutation programs | Strict parsing, length caps, underflow/unknown-opcode errors |
-
-### Out of Scope
-
-| Threat | Reason |
-| ---------------------------------- | ---------------------------------------- |
-| Real browser with real human input | Indistinguishable from a legitimate user |
-| WASM reverse engineering | Obfuscation is not a security primitive |
-| Server-side compromise | Outside the scope of client attestation |
-
-ChronoSeal raises cost and complexity of automated access. It is not a
-cryptographic proof of humanity and does not claim to be.
-
----
-
-## Module Reference
-
-| Path | Purpose |
-| ------------------------------------- | -------------------------------------------------------------------- |
-| `shared/src/protocol.rs` | Shared types: `InitRequest`, `HeartbeatRequest`, `StackState`, … |
-| `shared/src/hashing.rs` | `initial_hash`, `next_chain_hash`, `hash_stack` |
-| `shared/src/constants.rs` | All tunable parameters |
-| `shared/src/gene.rs` | Gene model, deterministic commitment (`chronoseal/gene/v1`) [v0.6.0] |
-| `shared/src/vm_extensions.rs` | Mutation opcode set, shared engine for server/WASM parity [v0.6.0] |
-| `server/src/routes/init.rs` | `POST /init` handler |
-| `server/src/routes/heartbeat.rs` | `POST /hb` handler |
-| `server/src/session.rs` | `create_session`, `verify_heartbeat`, `validate_mutation_parity` |
-| `server/src/crypto.rs` | `verify_signature` — BTreeMap canonical JSON |
-| `server/src/trust.rs` | `validate_mouse` — speed, distance, pauses |
-| `server/src/fingerprint.rs` | `validate` — aspect ratio, DPR, HW concurrency |
-| `server/src/vm.rs` | `generate_random_program` |
-| `server/src/ratelimit.rs` | `RateLimiter::check`, `evict_stale` |
-| `server/src/cleanup.rs` | Background loop: expire sessions + evict rate limiter |
-| `server/src/storage.rs` | SQLite init, backend selection, `current_time_ms` |
-| `wasm/src/crypto.rs` | `generate_keypair`, `sign_message`, `compute_next_hash` |
-| `wasm/src/vm.rs` | `run_program` — stack machine executor |
-| `wasm/src/vm_extensions.rs` | `preview_mutation`, `commit_mutation` [v0.6.0] |
-| `frontend/heartbeat.js` | Session init, heartbeat loop, chain advancement |
-| `frontend/entropy.js` | Mouse event ring buffer, `collectEntropy` |
-| `frontend/transport.js` | `sendRequest` fetch wrapper |
+* browser clients can execute WASM
+* heartbeats will arrive every 12–25 seconds
+* session state can be safely persisted in SQLite or Valkey
+* service operators want Unix-native systemd deployment and observability
diff --git a/docs/DEPLOYMENT.md b/docs/DEPLOYMENT.md
index 3974242..1984431 100644
--- a/docs/DEPLOYMENT.md
+++ b/docs/DEPLOYMENT.md
@@ -1,32 +1,37 @@
-# ChronoSeal — Deployment Guide
+# ChronoSeal Deployment Guide
+
+ChronoSeal v0.6.0 is designed for production deployment as a Unix-native daemon with hardened systemd support, lightweight WASM client runtime, and flexible backend storage.
## Prerequisites
| Tool | Minimum version | Purpose |
|---|---|---|
-| Rust | 1.87 stable | Server + WASM compilation |
+| Rust | 1.87 stable | Server and WASM compilation |
| wasm-pack | 0.13 | WASM build and packaging |
-| Docker + Compose | 24 / 2.x | Container deployment |
-| nginx / NPM / HAProxy | any | TLS termination, reverse proxy |
+| Docker | 24.x | Optional container deployment |
+| docker-compose | 2.x | Optional local orchestration |
+| systemd | 248+ | Service management |
-Install Rust: https://rustup.rs
+Install Rust: [https://rustup.rs](https://rustup.rs)
Install wasm-pack: `cargo install wasm-pack`
---
-## Build
+## Build Steps
### 1. Build the WASM module
```bash
+rustup target add wasm32-unknown-unknown
+cargo install wasm-pack
wasm-pack build wasm --target web --release
+rm -rf frontend/pkg
mv wasm/pkg frontend/pkg
```
-This produces `frontend/pkg/antibot_wasm.js` and `frontend/pkg/antibot_wasm_bg.wasm`,
-which are loaded by `frontend/main.js` at runtime.
+This produces the browser runtime assets required by the frontend and the server static file handler.
-### 2. Build the server
+### 2. Build the server binary
```bash
cargo build -p server --release
@@ -34,158 +39,109 @@ cargo build -p server --release
Binary output: `target/release/server`
-### 3. Build both (convenience script)
+### 3. Convenience script
```bash
bash scripts/build.sh
```
----
-
-## Running
-
-### Development
-
-```bash
-bash scripts/dev.sh
-```
-
-Runs the server with `cargo run --release`. The server serves the `frontend/`
-directory statically at `/` via tower-http `ServeDir`.
-
-Open `http://localhost:3000` in a browser. Open DevTools console — heartbeats
-should appear every 12–25 seconds. No visible UI is rendered; the protection
-is entirely silent.
-
-### Production (native binary)
-
-```bash
-cargo build -p server --release
-sudo cp target/release/server /usr/local/bin/chronoseal
-```
-
-Set environment variables before running:
-
-```bash
-export RUST_LOG=info # or warn for quieter output
-chronoseal
-```
-
-The server binds to `0.0.0.0:3000` by default. Place behind a reverse proxy
-for TLS — do not expose port 3000 directly.
+This script builds the WASM module, moves the generated package into `frontend/pkg`, and builds the server binary.
---
-## systemd
+## Deploying as a Native Service
-### Service file
-
-The provided `chronoseal.service` includes hardened systemd sandboxing:
-
-```
-NoNewPrivileges=true
-PrivateTmp=true
-ProtectSystem=strict
-ProtectHome=true
-ProtectKernelTunables=true
-ProtectKernelModules=true
-ProtectControlGroups=true
-MemoryDenyWriteExecute=true
-RestrictRealtime=true
-RestrictSUIDSGID=true
-LockPersonality=true
-SystemCallArchitectures=native
-```
+ChronoSeal is intended to run as a proper Unix daemon managed by systemd.
### Install
```bash
-# Create a dedicated system user
-sudo useradd --system --no-create-home --shell /usr/sbin/nologin chronoseal
-
-# Install binary and frontend
-sudo cp target/release/server /usr/local/bin/chronoseal
-sudo mkdir -p /opt/chronoseal/frontend
-sudo cp -r frontend/ /opt/chronoseal/frontend/
-sudo chown -R chronoseal:chronoseal /opt/chronoseal
-
-# Install and enable service
-sudo cp chronoseal.service /etc/systemd/system/
-sudo systemctl daemon-reload
-sudo systemctl enable --now chronoseal
+sudo bash scripts/install.sh
```
-### Verify
+This installer should perform the following tasks:
+
+* create a system user for `chronoseal`
+* install the server binary into `/usr/local/bin/chronoseal`
+* install static frontend assets into `/opt/chronoseal/frontend`
+* install `chronoseal.service` into `/etc/systemd/system/`
+* enable and start the service
+
+### Verify the service
```bash
sudo systemctl status chronoseal
-journalctl -u chronoseal -f
+sudo journalctl -u chronoseal -f
```
+### Recommended runtime options
+
+Use structured info-level logging in production:
+
+```bash
+export RUST_LOG=info
+sudo systemctl restart chronoseal
+```
+
+Avoid `RUST_LOG=debug` in production because debug logs can expose internal session identifiers.
+
---
-## Docker
+## systemd Integration
-### Build and run
+The supplied `chronoseal.service` is designed for hardened Unix-native operation.
-```bash
-docker compose up -d --build
-```
+Recommended service options:
-### docker-compose.yml overview
+* `NoNewPrivileges=true`
+* `PrivateTmp=true`
+* `ProtectSystem=strict`
+* `ProtectHome=true`
+* `ProtectKernelTunables=true`
+* `ProtectKernelModules=true`
+* `ProtectControlGroups=true`
+* `MemoryDenyWriteExecute=true`
+* `RestrictRealtime=true`
+* `RestrictSUIDSGID=true`
+* `SystemCallArchitectures=native`
-```yaml
-services:
- chronoseal:
- build: .
- restart: unless-stopped
- ports:
- - "3000:3000"
- environment:
- RUST_LOG: info
- tmpfs:
- - /tmp
-```
-
-The `tmpfs` mount ensures the in-memory SQLite database is never written to
-disk, even if Docker's storage driver were to flush the container filesystem.
-
-### Dockerfile stages
-
-The Dockerfile uses a two-stage build:
-
-1. `rust:1.87-bookworm` — compiles the server binary
-2. `debian:bookworm-slim` — minimal runtime image with only `ca-certificates`
-
-The WASM module and frontend must be built separately (wasm-pack requires a
-browser toolchain not present in the server image) and mounted or copied into
-the container at `/opt/chronoseal/frontend/`.
-
-```bash
-# Build WASM first
-wasm-pack build wasm --target web --release
-mv wasm/pkg frontend/pkg
-
-# Then build and run the container
-docker compose up -d --build
-```
-
-Or mount the pre-built frontend as a volume:
-
-```yaml
-volumes:
- - ./frontend:/opt/chronoseal/frontend:ro
-```
+These options reduce the host attack surface and keep the daemon constrained to its required runtime privileges.
---
-## Reverse Proxy
+## Configuration
-ChronoSeal must be served over HTTPS. The heartbeat payload contains a
-timestamp; if traffic is observable in plaintext, timing attacks become
-easier. TLS 1.3 is strongly recommended.
+ChronoSeal reads configuration from a TOML file, environment variables, and CLI overrides. Use `chronoseal config` to validate the effective configuration.
-### nginx
+Example runtime configuration options:
+
+```toml
+bind = "0.0.0.0:3000"
+pid_file = "/run/chronoseal.pid"
+log_level = "info"
+db_type = "sqlite-in-memory"
+db_path = "/var/lib/chronoseal/chronoseal.db"
+```
+
+### Supported `db_type`
+
+* `sqlite-in-memory`
+* `sqlite-disk`
+* `valkey`
+
+`sqlite-in-memory` is the default and preserves ephemeral session semantics.
+
+`sqlite-disk` will persist session state to a file specified by `db_path`.
+
+`valkey` selects the Valkey-compatible backend mode and may be useful for future deployment scenarios.
+
+---
+
+## Reverse Proxy and TLS
+
+ChronoSeal should be served over HTTPS in production. The heartbeat protocol includes timestamps and entropy data; serving that traffic in plaintext weakens security and allows easier traffic analysis.
+
+### nginx example
```nginx
server {
@@ -197,7 +153,6 @@ server {
ssl_protocols TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
- # Tight timeouts — heartbeat interval is 12–25s
proxy_read_timeout 35s;
proxy_send_timeout 10s;
@@ -218,129 +173,36 @@ server {
}
```
-### Nginx Proxy Manager
-
-1. Add a new Proxy Host pointing to `http://chronoseal:3000`
-2. Enable SSL, Request Let's Encrypt certificate
-3. Enable HTTP/2, Force SSL
-4. Under Advanced, add:
- ```
- proxy_read_timeout 35s;
- proxy_send_timeout 10s;
- ```
-
-### HAProxy
-
-```haproxy
-frontend https_front
- bind *:443 ssl crt /etc/haproxy/certs/your.domain.pem alpn h2,http/1.1
- default_backend chronoseal_back
-
-backend chronoseal_back
- server chronoseal 127.0.0.1:3000 check
- timeout connect 5s
- timeout server 35s
-```
-
----
-
-## Integration into an Existing Site
-
-ChronoSeal is designed to run as a sidecar — its `/init` and `/hb` endpoints
-can be proxied from any existing web server. The frontend assets (`pkg/`) need
-to be served from the same origin as the protected page (or CORS must be
-configured).
-
-### Option A — Serve everything from ChronoSeal
-
-ChronoSeal serves `frontend/` statically. Put your protected HTML inside
-`frontend/` and let ChronoSeal serve it directly.
-
-### Option B — Proxy only the API endpoints
-
-Keep your existing server. Proxy `/init` and `/hb` to ChronoSeal, and serve
-the WASM and JS assets from your CDN or existing static file server.
-
-```nginx
-# On your existing server:
-location ~ ^/(init|hb)$ {
- proxy_pass http://127.0.0.1:3000;
-}
-```
-
-Add to your protected pages:
-
-```html
-
-
-```
-
----
-
-## Configuration
-
-All parameters are in `shared/src/constants.rs`. Recompile after changes.
-
-| Constant | Default | Notes |
-|---|---|---|
-| `SESSION_ID_LEN` | 32 bytes | 256-bit entropy — do not reduce |
-| `SALT_LEN` | 16 bytes | Per-heartbeat salt |
-| `HEARTBEAT_MIN_INTERVAL_MS` | 12 000 ms | Increase to reduce server load |
-| `HEARTBEAT_MAX_INTERVAL_MS` | 25 000 ms | Jitter upper bound |
-| `EXPIRATION_MINUTES` | 30 min | Session TTL after last heartbeat |
-| `RATE_LIMIT_COUNT` | 5 | Max heartbeats per window per session |
-| `RATE_LIMIT_WINDOW_SECS` | 10 s | Rate limit window |
-| `MAX_TIMESTAMP_DRIFT_MS` | 30 000 ms | Anti-replay window; account for NTP skew |
-| `MIN_MOUSE_TOTAL_DIST` | 10.0 px | Lower for low-activity pages |
-| `MAX_MOUSE_AVG_SPEED` | 2.0 px/ms | Raise if legitimate users are rejected |
-| `MIN_PAUSE_COUNT` | 1 | Minimum natural pause events |
-
----
-
-## Observability
-
-ChronoSeal uses `tracing` with `tracing-subscriber`. Log levels:
-
-| Level | Events |
-|---|---|
-| `INFO` | Server start, request method + path + status |
-| `WARN` | Heartbeat validation failures (with session ID and reason) |
-| `DEBUG` | Rate limit hits |
+### Docker deployment
```bash
-RUST_LOG=info chronoseal # production
-RUST_LOG=debug chronoseal # development
-RUST_LOG=warn chronoseal # minimal output
+docker compose up -d --build
```
-Log format is plain text to stdout. Pipe to `journald`, `fluentd`, or any
-log aggregator via stdout capture.
+The supplied `docker-compose.yml` is intended for local evaluation and development. It mounts `frontend/` and exposes port `3000`.
+
+Note: build the WASM package before container startup, or mount a pre-built `frontend/pkg/` volume.
---
-## Health Check
+## Production Best Practices
-The server has no dedicated `/health` endpoint. Use a TCP check on port 3000,
-or a lightweight HTTP check on `GET /` (which serves `index.html`).
-
-```bash
-# Docker health check (add to docker-compose.yml if needed)
-healthcheck:
- test: ["CMD", "curl", "-sf", "http://localhost:3000/"]
- interval: 30s
- timeout: 5s
- retries: 3
-```
+* Use TLS termination at the perimeter
+* Run ChronoSeal behind a reverse proxy or firewall
+* Keep `RUST_LOG` at `info` or `warn`
+* Use `systemctl` for lifecycle management
+* Monitor `chronoseal` metrics with Prometheus
+* Place the frontend under the same origin as the protected pages or configure CORS carefully
---
-## Security Checklist
+## Health and Metrics
-- [ ] TLS 1.3 enabled, TLS 1.0/1.1 disabled
-- [ ] HTTP/2 enabled
-- [ ] Port 3000 not exposed to the public internet (only via reverse proxy)
-- [ ] `RUST_LOG=warn` or `info` in production (not `debug` — session IDs appear in logs)
-- [ ] systemd service running as `chronoseal` user with hardened sandbox
-- [ ] `MemoryDenyWriteExecute=true` in service file (prevents JIT in process)
-- [ ] CORS `CorsLayer::permissive()` replaced with origin-restricted policy for production
-- [ ] Frontend assets served over the same HTTPS origin as protected pages
+ChronoSeal exposes runtime endpoints for health and metrics.
+
+* `chronoseal health` — health probe
+* `chronoseal metrics` — Prometheus metrics output
+* `chronoseal status` — runtime status report
+* `chronoseal stats` — runtime statistics
+
+These endpoints are accessible locally from the daemon and may be proxied or scraped by monitoring infrastructure.
diff --git a/docs/DESIGN-PHILOSOPHY.md b/docs/DESIGN-PHILOSOPHY.md
index a3dd9e5..1f0fc98 100644
--- a/docs/DESIGN-PHILOSOPHY.md
+++ b/docs/DESIGN-PHILOSOPHY.md
@@ -1,41 +1,58 @@
# ChronoSeal Design Philosophy
-**"Everything is a File" — Unix-Native Software Design**
+ChronoSeal is built for operators who value clarity, stability, and Unix-native infrastructure.
-ChronoSeal is intentionally built as a **first-class citizen of Linux**. The entire application is designed to behave like a well-engineered native file within the Unix filesystem.
+## Core Philosophy
-### Why This Philosophy Matters
+ChronoSeal is a Unix-first, CLI-first cryptographic attestation daemon. It is intentionally designed to feel like infrastructure software such as `nginx`, `redis-server`, or `systemd` itself.
-ChronoSeal is designed so that administrators can operate, monitor, configure, and integrate it using the same reliable, transparent, and trusted tools and patterns they already use on Linux systems — without fighting the operating environment.
+### Design priorities
-### Core Principles
+* **Unix-native operation** — systemd integration, PID files, structured logs, and predictable lifecycle semantics.
+* **CLI as source of truth** — all runtime operations available through the command line.
+* **Minimal opacity** — no hidden telemetry, no opaque fingerprinting database.
+* **Privacy-first** — ephemeral session state and no persistent user profiling.
+* **Deterministic runtime behavior** — shared Rust/WASM implementation for the mutation engine and heartbeat protocol.
+* **Incremental cost escalation** — make automation painful to scale without claiming impossible security.
+* **Operational transparency** — expose health, metrics, status, and config as first-class artifacts.
-- **Everything is a File**: The application must be controllable, inspectable, and composable through standard Unix interfaces (CLI, files, signals, pipes, and environment).
-- **CLI as Source of Truth**: All operations — starting, stopping, configuring, monitoring, and debugging — must be possible from the command line with excellent discoverability.
-- **Behave Like a Native File**: Predictable lifecycle management through commands, signals (`SIGHUP`, `SIGTERM`, `SIGUSR1`), logs, configuration files, and standard process semantics.
-- **Composability**: Must work naturally with pipes, redirection, scripts, systemd, Ansible, Docker, and orchestration tools.
-- **Observability by Default**: All important state and metrics should be accessible as text or structured data.
-- **Minimal Friction, Maximum Durability**: One-line installer, world-class `--help`, proper man pages, and decades-long maintainability are non-negotiable.
-- **Respect for the OS**: Follows Linux Filesystem Hierarchy Standard (FHS), XDG Base Directory specification, and hardened systemd practices.
+## Execution Model
-### Non-Goals
+ChronoSeal emphasizes deterministic, stateless request validation with a lightweight server-side session store.
-ChronoSeal is **not** designed to be:
-- Cloud-first or vendor-specific
-- Browser-first or JavaScript-heavy
-- Dependency-heavy or framework-driven
-- GUI-centric (any graphical interface must be a thin wrapper)
-- Telemetry-oriented or privacy-invasive
-- Optimized for rapid prototyping at the cost of long-term reliability
+* The server persists only the small session state required for continuity.
+* The client executes a deterministic WASM runtime for every heartbeat.
+* The protocol is intentionally ambiguous on rejection to avoid leaking validation rules.
-These non-goals help keep the project focused on stability, simplicity, security, and deep Unix integration.
+## Non-Goals
-### Development Mindset
+ChronoSeal does not aim to be:
-- Production robustness, security, and long-term sustainability take clear precedence over development speed.
-- Every design decision is evaluated against one question:
- **“Does this make ChronoSeal feel like it naturally belongs in `/usr/bin/`?”**
+* a tracking platform
+* a browser fingerprinting database
+* a long-term behavioral analytics engine
+* a platform for user profiling
+* a SaaS or cloud-first service
-This philosophy guided the complete refactoring of ChronoSeal and continues to drive all future development.
+Instead, ChronoSeal aims to be an infrastructure layer that raises attacker cost while leaving legitimate users unobstructed.
-**Status**: Core architecture and systemd integration completed. Rich CLI, runtime configuration system, and one-line installer are in active development.
\ No newline at end of file
+## Operational Assumptions
+
+ChronoSeal assumes:
+
+* the host environment is Linux
+* systemd is available for service management
+* TLS is used in production
+* browser clients can execute WASM
+* operators can manage native binaries and configuration files
+
+## Privacy and Trust
+
+The project is designed so that the verification mechanism is:
+
+* ephemeral
+* difficult to reverse-engineer at scale
+* not based on personal identifiers
+* not dependent on long-term user history
+
+These choices reflect the belief that the best anti-automation system is one that can be operated without becoming a surveillance platform.
diff --git a/docs/PRIVACY POLICY.md b/docs/PRIVACY POLICY.md
index bb9d9ab..3144f08 100644
--- a/docs/PRIVACY POLICY.md
+++ b/docs/PRIVACY POLICY.md
@@ -1,278 +1,66 @@
-# ChronoSeal Privacy & Design Principles
+# ChronoSeal Privacy Policy
-## Privacy-First Browser Attestation Framework
+ChronoSeal is a privacy-first cryptographic attestation system. It is intentionally designed to avoid long-term profiling, tracking, and persistent identity storage.
-ChronoSeal is a lightweight, privacy-first browser attestation framework designed to resist:
+## What ChronoSeal Collects
-- automated bots
-- AI-driven browser automation
-- scripted abuse
-- browser surveillance ecosystems
+ChronoSeal only collects the minimum ephemeral data required to validate a live browser session:
-Unlike conventional anti-bot systems, ChronoSeal is intentionally designed to operate **without collecting or storing client identity data**.
+* `session_id` — ephemeral session identifier
+* `prev_hash` / `initial_hash` — cryptographic chain state
+* `timestamp` — heartbeat timing information
+* `entropy_data` — recent mouse event samples for behavioral plausibility
+* `stack_state` — VM execution result for heartbeat uniqueness
+* `fingerprint` signals — basic browser sanity values such as aspect ratio, DPR, and hardware concurrency
+* `mutation_step` / `gene_commitment` — synthetic mutation parity values for protocol continuity
----
+## What ChronoSeal Does Not Store
-# Core Philosophy
+ChronoSeal does not store or persist:
-ChronoSeal verifies:
+* IP addresses as a core artifact
+* browser history
+* user identifiers
+* personal data
+* device fingerprint databases
+* long-term behavioral profiles
+* cross-session tracking records
-- session continuity
-- runtime coherence
-- cryptographic synchronization
+If you need browser telemetry or user profiling, ChronoSeal is not the right tool.
-It does **not** verify:
+## Session Ephemerality
-- personal identity
-- browsing history
-- behavioral profiles
-- long-term reputation
+By default, ChronoSeal uses `sqlite-in-memory` storage. Sessions are ephemeral and are expected to be recreated after process restarts.
-The framework is built around one principle:
+Persistent state is only stored when the operator explicitly configures `sqlite-disk` or `valkey`.
-> Verify live browser participation without turning users into telemetry.
+## Client-Side Key Handling
----
+The Ed25519 signing keypair is generated inside the WASM runtime and is never serialized or transmitted in full.
-# Privacy-First By Architecture
+* Private key: stays inside WASM linear memory
+* Public key: transmitted once during session initialization
-ChronoSeal is intentionally engineered to avoid becoming:
+This design minimizes the amount of sensitive material exposed outside the browser runtime.
-- a tracking platform
-- a fingerprinting database
-- a telemetry pipeline
-- a surveillance system
+## Intentional Silent Rejection
-## ChronoSeal Does NOT Store
+ChronoSeal intentionally returns a uniform `{"status":"ok"}` response for invalid heartbeats.
-- IP addresses
-- Browser history
-- Persistent fingerprints
-- User profiles
-- Behavioral telemetry
-- Tracking identifiers
-- Device databases
-- Long-term session history
-- Cross-site correlation data
+This is a privacy-preserving decision: it avoids emitting detailed rejection reasons that could be used to fingerprint or probe clients.
-No client-side personal information is persisted.
+## Data Retention
----
+Session state is retained only as long as it is needed for heartbeat continuity.
-# Stateless Trust Model
+Expired sessions are purged automatically by cleanup tasks. Ephemeral backend modes do not write state to disk beyond the current process lifetime.
-ChronoSeal focuses on:
+## Transparency
-- ephemeral runtime verification
-- cryptographic continuity
-- synchronized challenge progression
-- live execution integrity
+The source code is open and the verification model is documented. Operators can inspect exactly what ChronoSeal stores and validates.
-The server only validates:
+## Summary
-- whether the current browser session behaves like a coherent participant *right now*
+ChronoSeal is designed to provide anti-automation defense without becoming a tracking or surveillance platform.
-ChronoSeal does not maintain:
-
-- user identity databases
-- reputation systems
-- persistent surveillance records
-
----
-
-# Anti-Bot Without Surveillance
-
-Most modern anti-bot systems rely heavily on:
-
-- fingerprinting
-- behavioral tracking
-- telemetry aggregation
-- centralized analytics
-
-ChronoSeal deliberately rejects this model.
-
-Instead, ChronoSeal uses:
-
-- synchronized cryptographic chains
-- WASM-isolated signing
-- protocol continuity
-- transient verification state
-
-This provides bot resistance while preserving user privacy.
-
----
-
-# Lightweight By Design
-
-ChronoSeal is intentionally engineered to remain:
-
-- compact
-- dependency-light
-- operationally simple
-- Unix-native
-
-## Current Footprint
-
-### Server Binary
-
-Compiled x86_64 Linux server binary:
-
-- ~8.4 MB
-
-### WASM Runtime
-
-`chronoseal_wasm_bg.wasm`
-
-- ~218 KB
-
-### Full WASM Package
-
-Entire generated WASM package:
-
-- ~720 KB
-
-Includes:
-
-- WASM runtime
-- JavaScript glue code
-- Type definitions
-
----
-
-# No Frontend Framework Dependency
-
-ChronoSeal does not depend on:
-
-- React
-- Angular
-- Vue
-- Electron
-- Node.js runtime
-- Browser bundler ecosystems
-
-The browser runtime uses:
-
-- native ES modules
-- direct WebAssembly loading
-- lightweight JavaScript glue
-
-This minimizes:
-
-- dependency complexity
-- supply-chain risk
-- build fragility
-- browser overhead
-
----
-
-# Clean Repository Philosophy
-
-ChronoSeal keeps generated artefacts out of version control.
-
-## What Is NOT Stored In The Repository
-
-| Path | Reason |
-|---|---|
-| `wasm/pkg/` | Generated build output |
-| `frontend/pkg/` | Generated serve-time artefacts |
-| `target/` | Standard Rust build artefacts |
-
-Generated binaries change frequently and are reproducible from source.
-
-The repository intentionally stores:
-
-- source code
-- architecture
-- reproducible build logic only
-
----
-
-# Unix-Native Operational Model
-
-ChronoSeal is designed as:
-
-- infrastructure software
-- not browser-centric SaaS
-
-Core operational principles:
-
-- CLI-first operation
-- systemd-native deployment
-- structured logs
-- explicit configuration
-- inspectable runtime behavior
-- minimal hidden state
-
-ChronoSeal should feel natural on Linux systems:
-
-- simple to deploy
-- easy to audit
-- understandable years later
-
----
-
-# Security Through Operational Asymmetry
-
-ChronoSeal increases attacker cost through:
-
-- synchronization burden
-- runtime continuity requirements
-- WASM-isolated cryptographic execution
-- chained session progression
-
-It does not attempt:
-
-- invasive tracking
-- permanent identification
-- surveillance-driven scoring
-
----
-
-# Design Goals
-
-ChronoSeal prioritizes:
-
-- Privacy
-- Simplicity
-- Transparency
-- Operational clarity
-- Long-term maintainability
-- Minimalism
-- Unix-native behavior
-- Low deployment friction
-
----
-
-# Non-Goals
-
-ChronoSeal is intentionally NOT:
-
-- A surveillance platform
-- A telemetry collection system
-- A browser fingerprinting database
-- An analytics engine
-- A cloud lock-in service
-- A JavaScript-heavy frontend platform
-- An advertising or tracking framework
-
----
-
-# Summary
-
-ChronoSeal is designed to prove:
-
-> “A live browser session is coherently participating right now.”
-
-without storing:
-
-- who the user is
-- where they came from
-- what they previously did
-
-It is a lightweight, privacy-preserving, Unix-native browser attestation framework focused on:
-
-- anti-bot resistance
-- anti-automation
-- operational simplicity
-
-without compromising user privacy.
\ No newline at end of file
+It is a privacy-aware, ephemeral attestation layer with strong operational guardrails.
diff --git a/docs/REFRACTORING-v0.6.0.md b/docs/REFRACTORING-v0.6.0.md
index af6e583..dea8b73 100644
--- a/docs/REFRACTORING-v0.6.0.md
+++ b/docs/REFRACTORING-v0.6.0.md
@@ -1,115 +1,118 @@
-# ChronoSeal v0.6.0 — Synthetic Gene Mutation System
+# ChronoSeal v0.6.0 — Refactoring and System Upgrade
-## Overview & Motivation
-ChronoSeal v0.6.0 introduces a synthetic mutation chain model to strengthen attestation liveness and anti-replay guarantees while preserving privacy-first behavior. The core model combines:
-- a primary byte-oriented gene buffer (`Vec`), and
-- a bounded secondary environment map (`Vec<(u16 symbol, u32 quantity)>`).
+ChronoSeal v0.6.0 is a major architecture and protocol update that transforms the project from a lightweight heartbeat service into a mature Unix-native attestation daemon with deterministic mutation parity and pluggable storage backends.
-Each heartbeat now carries deterministic mutation progression evidence (`mutation_step`, `gene_commitment`) that is validated server-side against the exact server-issued mutation order. This design increases attacker workload by coupling cryptographic chain continuity with stateful deterministic mutation parity.
+## Summary of Changes
-## Architectural Goals
-1. Keep runtime behavior deterministic across server and WASM execution.
-2. Preserve ephemerality and low operational complexity.
-3. Minimize additional latency on the heartbeat path.
-4. Improve protocol resistance against replay and mutation tampering.
-5. Maintain a maintainable codebase with explicit invariants and focused modules.
+* Introduced the **Synthetic Gene Mutation Engine** for deterministic mutation parity across server and WASM.
+* Added server-side validation of `mutation_step` and `gene_commitment`.
+* Centralized shared protocol logic in `shared/` for server/WASM parity.
+* Added support for multiple storage backend modes: `sqlite-in-memory`, `sqlite-disk`, and `valkey` compatibility.
+* Hardened runtime architecture with `systemd` readiness, graceful shutdown, PID file support, and structured logging.
+* Expanded CLI with rich subcommands and effective runtime configuration.
+* Preserved silent rejection semantics while improving anti-replay and liveness guarantees.
-## Design Decisions
-1. **Shared mutation engine**
- Mutation opcode semantics live in `shared/src/vm_extensions.rs` to guarantee server/client parity from one implementation.
+## Why This Refactor?
-2. **Deterministic gene commitment**
- A domain-separated BLAKE3 commitment (`chronoseal/gene/v1`) binds both gene bytes and sorted environment records.
+The previous model relied on heartbeat continuity and behavioral entropy alone. v0.6.0 strengthens the protocol by adding a second, deterministic state progression channel:
-3. **Bounded mutation complexity**
- Mutation program length is capped (`MAX_MUTATION_PROGRAM_BYTES`) and environment cardinality is capped (`MAX_ENV_RECORDS`).
+* each heartbeat now includes a mutation step and commitment
+* the server authoritatively selects the next mutation program
+* the client must preview and commit the same state locally in WASM
+* the server rejects any mismatch silently
-4. **Strict validation on ingest**
- Environment payloads are validated for sortedness, uniqueness, non-zero quantity, and length constraints.
+This raises the cost of developing a successful automation attack because the attacker must now maintain both a valid chain and a valid mutation progression state.
-5. **Protocol-level mutation handshake**
- `InitResponse` and `Heartbeat` payloads now include mutation step/order and commitment fields.
+## Core Architecture Changes
-6. **DB backend control via `db_type`**
- Server CLI/config now supports:
- - `sqlite-in-memory` (default)
- - `sqlite-in-disk` (active; uses `db_path`)
- - `valkey` (active compatibility mode; currently falls back to in-memory)
+### Shared Protocol Code
-## Implementation Plan
-1. Add gene model + deterministic commitment in `shared/gene.rs`.
-2. Implement v0.6.0 mutation opcode set in shared VM extensions.
-3. Persist mutation state per session (`gene`, `environment`, `pending_mutation`, `pending_mutation_step`).
-4. Extend protocol schema for mutation fields in init/heartbeat exchange.
-5. Validate mutation step + commitment parity before accepting heartbeat updates.
-6. Add WASM preview/commit mutation lifecycle mirroring server behavior.
-7. Add `db_type` CLI/config flow and runtime backend initialization strategy.
-8. Add migration-safe schema extension (column existence checks + index creation).
+`shared/` now contains:
-## Testing Strategy (detailed section)
-ChronoSeal v0.6.0 test coverage is organized across unit, integration, and randomized/fuzz-style validation.
+* gene model and commitment hashing
+* mutation opcode semantics
+* request/response payload structures
+* canonical signing support
+* VM execution logic shared by server and WASM
-1. **Unit, integration, and property tests**
- - Unit tests for gene invariants and encoding/decoding.
- - Unit tests for every mutation opcode with stack-effect assertions.
- - Integration tests for full session lifecycle and heartbeat acceptance/rejection paths.
- - Table-driven randomized tests and fuzz-style random bytecode tests to validate deterministic failure/success symmetry.
+Moving mutation semantics into `shared/` eliminates subtle server/client divergence bugs and enables deterministic cross-runtime testing.
-2. **Server-client parity testing**
- - Shared opcode engine parity tests across seeded mutation sequences.
- - Multi-step mutation chain test (`test_mutation_chain`) asserting identical server/client final state.
- - 10+ heartbeat deterministic simulation tests in session integration suite.
+### Mutation Handshake
-3. **Evasion / attack simulation testing**
- - Replay attack simulation.
- - Mutation step mismatch rejection.
- - Mutation commitment tampering rejection.
- - Malformed server mutation payload rejection.
- - Stack underflow / unknown opcode / truncated program rejection.
+v0.6.0 adds the following data to the protocol:
-4. **Performance regression testing**
- - Bounded execution checks through capped program size and bounded record counts.
- - Timing smoke regression test for mutation execution loops.
- - End-to-end heartbeat test coverage to detect behavior regressions on hot paths.
+* `mutation_step`
+* `mutation_order_b64`
+* `gene_commitment`
+* `next_mutation_step`
+* `next_mutation_order_b64`
-## Security Analysis
-1. **Replay resistance**
- Heartbeats are now tied to both chain hash and mutation step progression.
+These fields are now part of the session initialization and heartbeat exchange.
-2. **Mutation tampering resistance**
- Server recomputes candidate gene state from authoritative pending mutation program and rejects commitment mismatch.
+### Server Session State
-3. **Protocol ambiguity reduction**
- Canonical signing payload includes mutation fields, reducing exploitable unsigned state.
+The session schema now stores:
-4. **Input hardening**
- Program size limits, stack underflow checks, and strict environment decoding reduce parser abuse and malformed payload amplification.
+* committed gene bytes
+* committed environment records
+* pending mutation order
+* pending mutation step
-5. **Deterministic failure semantics**
- Invalid mutation instructions fail predictably and symmetrically across server and WASM paths.
+The server advances this state only after a heartbeat is accepted.
-## Performance Considerations
-1. Mutation instructions are lightweight and mostly O(1); only `INSERT`/`DELETE` are O(n) but bounded by max gene size.
-2. Environment operations use sorted-vector binary search with tight upper bound (`MAX_ENV_RECORDS`).
-3. Commitment hashing is linear in gene size and record count, both bounded.
-4. Shared engine avoids duplicate logic and divergence-induced debugging overhead.
+### Deterministic WASM Preview
-## Migration & Backward Compatibility
-1. Schema migration is additive; new columns are created when missing.
-2. Existing deployments without mutation fields require updated client+server pair for heartbeat compatibility.
-3. `db_type` defaults to in-memory to preserve ephemeral behavior.
-4. `sqlite-in-disk` is now directly usable via `db_path`.
-5. `valkey` currently runs in compatibility mode (in-memory fallback) to avoid startup failure while preserving CLI contract.
+The WASM runtime exposes:
-## Risks & Mitigations
-1. **Risk: State divergence between server and client**
- Mitigation: shared opcode engine + deterministic seeded parity tests + multi-heartbeat integration tests.
+* `init_gene_state()`
+* `preview_gene_commitment()`
+* `commit_gene_preview()`
+* `discard_gene_preview()`
+* `current_gene_commitment()`
-2. **Risk: Mutation opcode abuse via malformed programs**
- Mitigation: strict parsing, length caps, explicit underflow/unknown-opcode errors.
+This makes the client-side mutation lifecycle explicit and deterministic.
-3. **Risk: Performance regressions**
- Mitigation: bounded structures, smoke timing tests, and focused hot-path validation.
+### Backend Abstraction
-4. **Risk: Backend confusion during `db_type` rollout**
- Mitigation: explicit CLI command (`chronoseal db-type`), config output visibility, and clear runtime compatibility behavior.
+The server runtime now supports a configurable `db_type`.
+
+* `sqlite-in-memory` — default runtime storage with ephemeral session semantics
+* `sqlite-disk` — persistent SQLite storage for stateful deployments
+* `valkey` — compatibility mode for alternative storage backends
+
+This abstraction makes ChronoSeal easier to operate in both stateless and stateful environments.
+
+### CLI and Service Integration
+
+v0.6.0 improves the CLI surface with operational commands and service introspection.
+
+* `chronoseal run`
+* `chronoseal status`
+* `chronoseal health`
+* `chronoseal config`
+* `chronoseal metrics`
+* `chronoseal stats`
+* `chronoseal db-type`
+* `chronoseal completion`
+* `chronoseal version`
+
+The runtime now includes PID file handling and graceful termination.
+
+## Testing and Validation
+
+The refactor includes extensive tests for:
+
+* server/WASM parity across mutation sequences
+* malformed mutation payload rejection
+* replay attack rejection
+* mutation step mismatch rejection
+* stateful session update semantics
+* runtime database mode validation
+
+The codebase now supports deterministic table-driven tests and fuzz-style random program validation.
+
+## Operational Impact
+
+This release makes ChronoSeal suitable for production deployment in Linux environments and for integration into existing web application stacks.
+
+The combination of deterministic mutation parity and shared protocol implementation improves both security and maintainability.
diff --git a/docs/THREAT_MODEL.md b/docs/THREAT_MODEL.md
index d0bccfe..5d4feef 100644
--- a/docs/THREAT_MODEL.md
+++ b/docs/THREAT_MODEL.md
@@ -1,205 +1,137 @@
-# ChronoSeal — Threat Model
+# ChronoSeal Threat Model
+
+ChronoSeal is a cost-raising cryptographic attestation daemon. It increases the burden on automated clients while preserving privacy, determinism, and operational transparency.
## Purpose
-This document defines what ChronoSeal is designed to protect against, what
-it explicitly does not protect against, and the reasoning behind each
-design decision in security terms.
+ChronoSeal protects web resources by making browser automation and replay attacks more expensive and fragile. It is not intended to be a perfect bot blocker.
-ChronoSeal is a **cost-raising mechanism**. It does not claim to make
-automated access impossible. It makes automated access expensive, complex
-to maintain, and operationally fragile at scale.
+## Protected Assets
----
-
-## Assets Being Protected
-
-| Asset | Description |
+| Asset | Protection focus |
|---|---|
-| Web page content | HTML, rendered data, scraped text |
-| API responses | JSON endpoints that serve structured data |
-| Server compute | CPU and bandwidth consumed by automated clients |
-| Rate-limited resources | Endpoints with per-user quotas |
-| Behavioral analytics | Metrics polluted by bot traffic |
-
----
+| Page content | Prevent automated scraping and replay of protected content |
+| API responses | Reduce scripted access to sensitive endpoints |
+| Server compute | Increase attacker resource costs |
+| Session continuity | Enforce live session progression |
+| Behavioral integrity | Validate plausible browser activity |
## Attacker Profiles
-### Level 1 — Script Kiddie / Commodity Scraper
+### Level 1 — Commodity Scraper
-**Tools:** `curl`, `requests`, `scrapy`, simple HTTP clients.
-**Capability:** No browser environment. Cannot execute JavaScript or WASM.
-**ChronoSeal response:** Session never initialises. No `session_id` is ever
-presented to `/hb`. Content gated behind session validation is never served.
+* Tools: `curl`, `requests`, headless HTTP clients
+* Capability: no WASM execution, no browser engine
+
+ChronoSeal response:
+
+* cannot initialize a session
+* no `session_id` is produced
+* content remains protected behind the attestation layer
### Level 2 — Headless Browser Operator
-**Tools:** Playwright, Puppeteer, Selenium, undetected-chromedriver.
-**Capability:** Full browser environment. Can execute JavaScript and WASM.
-Cannot easily synthesise realistic mouse entropy or maintain hash chain state
-across concurrent sessions.
-**ChronoSeal response:** Mouse entropy validation rejects absent or synthetic
-movement. Hash chain requires per-session state synchronisation. Scaling to
-hundreds of concurrent sessions requires proportional infrastructure.
+* Tools: Playwright, Puppeteer, Selenium
+* Capability: browser engine available, but automation is not indistinguishable from a real user
+
+ChronoSeal response:
+
+* mouse entropy and pause checks become active barriers
+* hash chain continuity requires per-session state tracking
+* synthetic heartbeats become expensive to maintain at scale
### Level 3 — Stealth Automation
-**Tools:** Puppeteer Stealth, rebrowser-patches, custom CDP clients with
-evasion patches.
-**Capability:** Patches `navigator.webdriver`, spoofs browser fingerprints,
-can inject synthetic mouse events. May partially pass behavioral checks.
-**ChronoSeal response:** Ed25519 signature over the full payload (including
-behavioral state and VM execution result) means the attacker must also
-correctly execute the WASM program and maintain chain continuity. The private
-key is generated fresh per page load and never exposed — it cannot be
-extracted from a legitimate session and reused.
+* Tools: browser stealth plugins, CDP patching, synthetic event injection
+* Capability: can execute JavaScript and WASM, may spoof some browser signals
-### Level 4 — Sophisticated Adversary
+ChronoSeal response:
-**Tools:** Full browser farm with real input devices, WASM reverse engineering,
-custom chain maintenance infrastructure.
-**Capability:** Can pass all current ChronoSeal checks given sufficient
-engineering effort.
-**ChronoSeal response:** Significantly increases operational cost. A browser
-farm with real input devices costs orders of magnitude more than a commodity
-scraper fleet. ChronoSeal is not designed to stop this attacker — no client-
-side protection can.
+* signature, hash chain, and mutation commitment require correct WASM execution
+* private key is generated per page load and never exposes raw key material
+* silent rejection hides validation rules from attacker feedback
----
+### Level 4 — Sophisticated Operator
+
+* Tools: real browser farms, hardware input devices, custom chain management
+* Capability: high engineering investment and real device scale
+
+ChronoSeal response:
+
+* significantly increases operational cost and complexity
+* forces a full protocol implementation rather than best-effort scraping
+* is not designed to stop such adversaries completely
## Attack Vectors and Mitigations
### Replay Attack
-**Attack:** Capture a valid heartbeat payload and retransmit it.
-**Mitigation:**
-- Timestamp window (±30 seconds): replayed payloads are rejected after 30s.
-- Hash chain: each heartbeat must present `H(n-1)` matching the server's
- stored state. A replayed heartbeat presents a stale hash that no longer
- matches after one successful heartbeat has advanced the chain.
+**Attack:** resend a previously observed heartbeat.
+
+**Mitigations:**
+
+* timestamp window enforcement (±30 seconds)
+* chained Blake3 hash continuity
+* server-issued salt rotation
+* mutation step progression
### Signature Forgery
-**Attack:** Construct a valid-looking heartbeat payload without the private key.
-**Mitigation:** Ed25519 with 128-bit security. The private key is generated
-inside WASM `thread_local` memory, never serialised, never passed to
-JavaScript, never transmitted. Forgery requires breaking Ed25519 or
-extracting the key from WASM memory — neither is practical.
+**Attack:** forge a heartbeat without the private key.
-### Key Extraction
+**Mitigations:**
-**Attack:** Inspect WASM linear memory to extract the private signing key.
-**Mitigation:** The key is stored in a Rust `thread_local! { RefCell