forge-reasoning 0.1.2

Reasoning tools for LLM debugging - checkpointing, hypotheses, contradictions
Documentation
# TDD Wave 2: Query Methods Implementation

**Date**: 2026-02-19  
**Focus**: Checkpoint retrieval, listing, and restoration

---

## Wave 2 Tests Summary

| Test | Description | Status |
|------|-------------|--------|
| 11 | Retrieve checkpoint by ID ||
| 12 | Get by ID returns None for non-existent ||
| 13 | List checkpoints by session ||
| 14 | Session isolation (checkpoints don't leak) ||
| 15 | List checkpoints by tag ||
| 16 | Restore checkpoint state ||
| 17 | Restore fails for invalid checkpoint ||
| 18 | Checkpoint ordering by timestamp ||
| 19 | Checkpoint summary has correct info ||
| 20 | List returns populated results ||

**Total**: 10 new tests, all passing (20/20 cumulative)

---

## Implementation Details

### New Methods Added to `TemporalCheckpointManager`

```rust
/// Get a checkpoint by ID
pub fn get(&self, id: &CheckpointId) -> Result<Option<TemporalCheckpoint>>

/// List checkpoints for a specific session
pub fn list_by_session(&self, session_id: &SessionId) -> Result<Vec<CheckpointSummary>>

/// List checkpoints with a specific tag
pub fn list_by_tag(&self, tag: &str) -> Result<Vec<CheckpointSummary>>

/// Create a checkpoint with tags
pub fn checkpoint_with_tags(
    &self,
    message: impl Into<String>,
    tags: Vec<String>,
) -> Result<CheckpointId>

/// Restore state from a checkpoint
pub fn restore(&self, checkpoint: &TemporalCheckpoint) -> Result<DebugStateSnapshot>

/// Get a summary of a checkpoint by ID
pub fn get_summary(&self, id: &CheckpointId) -> Result<Option<CheckpointSummary>>
```

### Storage Implementation Update

Added in-memory cache to `SqliteGraphStorage`:

```rust
pub struct SqliteGraphStorage {
    graph: RefCell<SqliteGraph>,
    cache: RefCell<HashMap<CheckpointId, TemporalCheckpoint>>,
}
```

**Rationale**: SQLiteGraph's query API is limited for complex filtering. The in-memory cache enables:
- O(1) lookup by ID
- Fast filtering by session_id and tags
- Simple implementation for MVP

**Future work**: Implement proper SQLite queries when sqlitegraph API supports it.

---

## Key Design Decisions

### 1. In-Memory Cache Pattern

For MVP, we use a hybrid approach:
- Store checkpoint in SQLiteGraph (persistence)
- Also store in HashMap cache (fast queries)

This gives us durability + query performance without complex SQL.

### 2. Session Isolation

Each `TemporalCheckpointManager` is bound to a session:
- `list()` returns only current session's checkpoints
- `list_by_session()` allows cross-session queries
- Sessions are isolated by `SessionId` (UUID)

### 3. Tag-Based Filtering

Tags are stored as `Vec<String>` on each checkpoint:
- Simple contains-check for filtering
- No index needed for MVP scale
- Can add database index later if needed

### 4. Restore Validation

Restore validates checkpoint state:
```rust
if checkpoint.state.working_dir.is_none() {
    return Err(ReasoningError::InvalidState(...));
}
```

This prevents restoring from corrupted/incomplete checkpoints.

---

## Code Metrics

| File | Lines | Change |
|------|-------|--------|
| `src/checkpoint.rs` | ~320 | +60 |
| `src/storage_sqlitegraph.rs` | ~165 | +70 |
| `tests/checkpoint_tests.rs` | ~350 | +220 |

---

## Next Wave Preview

**Wave 3: Persistence & Durability**
- File-based storage (not just in-memory)
- Checkpoint compaction/rotation
- Import/export functionality
- Error recovery

**Potential Wave 4: Thread Safety**
- Replace `Rc<RefCell>` with `Arc<Mutex>`
- Concurrent checkpoint operations
- Background persistence

---

## Running the Tests

```bash
cd /home/feanor/Projects/forge/forge-reasoning
cargo test

# Just Wave 2 tests
cargo test test_get_checkpoint
cargo test test_list
cargo test test_restore
```

---

**Wave 2 Complete** ✅