commonware-storage 2026.10.0

Persist and retrieve data from an abstract store.
Documentation
# Storage testing

Use the deterministic runtime's storage backend for storage tests. It permits reproducible I/O, crashes, corruption, and recovery without real disk access.

## Basic operations

```rust
#[test]
fn test_storage_operations() {
    let runner = deterministic::Runner::default();
    runner.start(|context| async move {
        let (blob, _) = context
            .open("partition_name", &0u64.to_be_bytes())
            .await
            .expect("open blob");

        blob.write_at(0, vec![1, 2, 3, 4], WriteOptions::default())
            .await
            .expect("write");
        let data = blob
            .read_at(0, 4, ReadOptions::default())
            .await
            .expect("read")
            .coalesce();
        assert_eq!(data.as_ref(), &[1, 2, 3, 4]);
        blob.sync().await.expect("sync");
    });
}
```

## Recovery and corruption

Persist data, drop the database, and initialize it again to test clean recovery. Before reinitializing, drop every blob handle and journal snapshot, and abort and join any task that holds one. Opening a blob that is still held returns `BlobAlreadyOpen`. To simulate an interrupted write, resize a blob after writing it; to simulate corruption, overwrite a checksum or truncate data. Reinitialize and verify that replay recovers to the last valid item.

```rust
let (blob, size) = context.open(&partition, &name).await.unwrap();
blob.resize(size - 1).await.unwrap();
blob.sync().await.unwrap();
drop(blob);

let journal = Journal::init(context, cfg).await.unwrap();
assert_eq!(journal.size().await.unwrap(), expected_size);
```

## What to cover

- Empty and single-item stores, maximum sizes, and offset overflow.
- Restart after a clean sync and after an unclean shutdown.
- Truncated, corrupted, and missing data.
- Multiple readers or writers and blob pruning.
- Metrics for tracked, synced, and pruned data.
- Hash-based conformance tests for intentionally stable storage formats.

Errors from mutable operations, including `put`, `delete`, and `sync`, are unrecoverable. A caller must not use that database again after such an error.