memory-crystal 0.1.0

Crystallized memory: lossy, reconstructive persistence for AI agents
Documentation
# memory-crystal

**Crystallized memory: lossy, reconstructive persistence for AI agents.**

Based on the [Tile Compression Theorem](https://en.wikipedia.org/wiki/Forgetting_curve) and Ebbinghaus forgetting curves. Memory Crystal implements the insight that human memory doesn't store verbatim records — it stores compressed tiles that are *reconstructed* on recall using context, and *decay* over time unless reinforced.

## Features

- **Lossy encoding** — compresses content into tiles with immortal constraints and compressed summaries
- **Context-dependent recall** — reconstructs memories differently depending on what context is available
- **Ebbinghaus decay** — memories fade following exponential forgetting curves, modified by emotional valence and access frequency
- **Reconsolidation** — recalling a memory resets its decay clock and can strengthen it (just like biological memory)
- **Telephone chains** — measure fact drift across successive lossy re-encodings
- **Disk persistence** — tiles are stored as JSON files, indexed in memory for fast queries
- **Constraint extraction** — automatically extracts proper nouns, numbers, and quoted strings as "immortal facts"

## Quick Start

```rust
use memory_crystal::{Crystal, SalienceMap};
use std::time::Duration;

// Open a crystal (directory on disk).
let mut crystal = Crystal::open("my_memories".as_ref())?;

// Crystallize a memory.
let id = crystal.crystallize(
    "Alice discovered a critical bug in production on March 15th.",
    SalienceMap { valence: Some(0.9), ..Default::default() },
)?;

// Recall with context (reconstruction depends on what you provide).
let rec = crystal.recall(&id, "production bug March")?;
println!("Confidence: {:.2}", rec.confidence);
println!("Content: {}", rec.content);
println!("Preserved facts: {:?}", rec.preserved_facts);

// Reconsolidate (strengthens memory, resets decay).
crystal.reconsolidate(&id, "The bug was in the connection pool")?;

// Forget old, low-valence memories.
let forgotten = crystal.forget(Duration::from_secs(30 * 24 * 3600))?;
println!("Forgot {} tiles", forgotten);
```

## Architecture

```
┌─────────────┐     ┌──────────────┐     ┌──────────────┐
│  TileEncoder │────▶│     Tile      │────▶│  TileDecoder  │
│ (lossy)      │     │ (crystal)     │     │ (reconstruct) │
└─────────────┘     └──────┬───────┘     └──────────────┘
                    ┌──────┴───────┐
                    │ DecaySchedule│
                    │ (forgetting) │
                    └──────────────┘
```

- **TileEncoder**: Compresses content into a tile with constraints, summary, valence
- **TileDecoder**: Reconstructs content from a tile using context, reporting confidence
- **DecaySchedule**: Ebbinghaus forgetting curve — high-valence tiles decay slower, frequent access slows decay
- **CrystalIndex**: In-memory index for constraint-based, valence-based, and time-based queries
- **TelephoneChain**: Measures fact survival across successive lossy re-encodings

## Core Concepts

### Tiles
A tile is a lossy compression of content. It preserves:
- **Constraints** (immortal facts): proper nouns, numbers, key phrases
- **Summary**: compressed text that fits within a rate limit
- **Valence**: emotional salience (0.0–1.0) — high-valence memories decay slower

### Decay
Retention follows: `R(t) = e^(-λt)` where λ depends on half-life, valence, and access count. Tiles below 10% retention are candidates for forgetting.

### Reconsolidation
Like biological memory, recalling a tile makes it modifiable. Reconsolidation resets the decay clock, increases valence slightly, and can add new context to the summary.

## Install

Add to your `Cargo.toml`:

```toml
[dependencies]
memory-crystal = "0.1.0"
```

## License

MIT