# Penrose Memory
Aperiodic memory palace for AI agents. Navigate memories by **distance + direction** on a Penrose floor.
## How It Works
1. **Project**: Embeddings → 2D Penrose coordinates via golden-ratio hashing
2. **Store**: Place memories on the floor at projected coordinates
3. **Recall**: Dead-reckon from query toward stored memories
4. **Navigate**: Walk from any tile by distance + heading
5. **Consolidate**: Merge nearby memories using golden hierarchy (φ^k)
The Fibonacci word determines tile bits (thick:thin → 1/φ). Matching rules verify valid positions. 3-coloring enables sharding.
## Install
```toml
[dependencies]
penrose-memory = "1.0.0"
```
Python:
```bash
pip install penrose-memory
```
## Quick Start (Rust)
```rust
use penrose_memory::PenroseMemory;
let mut pm = PenroseMemory::new(1536);
// Store an embedding with content
let id = pm.store(&embedding, 42);
// Recall by nearest embedding
let results = pm.recall(&query, 5);
for r in &results {
println!("id={} conf={:.3} dist={:.3}", r.tile_id, r.confidence, r.distance);
}
// Navigate from a tile
let nearby = pm.navigate(id, 2.5, std::f64::consts::FRAC_PI_4);
// Consolidate old memories
pm.consolidate();
```
## Quick Start (Python)
```python
from penrose_memory import PenroseMemory
pm = PenroseMemory(embedding_dim=1536)
# Store text with embedding
tile_id = pm.store("hello world", embedding)
# Recall by query embedding
results = pm.recall(query_embedding, max_steps=5)
for r in results:
print(r["text"], r["confidence"], r["distance"])
# Navigate from a tile
nearby = pm.navigate(tile_id, distance=2.5, heading=0.785)
# Consolidate
removed = pm.consolidate()
```
## API
### Rust
| `new(dim)` | Create with embedding dimension |
| `store(&[f64], u64) -> u64` | Store embedding + content, returns tile_id |
| `recall(&[f64], steps) -> Vec<RecallResult>` | Recall by dead reckoning |
| `navigate(id, dist, heading) -> Vec<u64>` | Navigate from tile |
| `consolidate()` | Merge nearby memories |
| `len() -> usize` | Memory count |
### Python
| `__init__(embedding_dim=1536)` | Create with embedding dimension |
| `store(text, embedding) -> int` | Store text + embedding |
| `recall(query_embedding, max_steps=5) -> list` | Recall by dead reckoning |
| `navigate(tile_id, distance, heading) -> list` | Navigate from tile |
| `consolidate() -> int` | Merge nearby memories |
| `__len__()` | Memory count |
## Tests
**Rust**: 15 tests covering roundtrip, aperiodicity, Fibonacci ratio, 3-coloring, consolidation, navigation, large embeddings, confidence decay, and more.
**Python**: 10 tests covering the same core functionality.
## License
MIT